微生物组数据的典型格式
大多数处理高通量扩增子数据的管道,例如mothur,QIIME和dada2,都会形成读取计数矩阵。该矩阵的一维(即行或列)由操作分类单位(OTU),系统型或精确序列变体(ESV)(通过各种方式“组合”相似的读取序列)组成。另一个维度包括样本。不同的工具将期望/输出矩阵的不同方向,但是在我们的例子中,列是样本,行是OTU。有时是OTU数据和丰度矩阵是两个单独的表。通常会有另一个表,其中的行有示例信息。这样可以轻松添加许多其他示例数据列,这些列可用于子集数据。每个样本和OTU都有唯一的ID。
将数据导入R
如果数据格式正确,则将数据导入R可能非常容易,但否则可能会非常令人沮丧。格式良好的数据的示例是.csv(逗号分隔值)或.tsv(制表符分隔值)文件,每个文件都有一个表,没有其他注释或格式(例如,合并的单元格)。这两种格式都可能具有.txt扩展名(扩展名实际上并不重要;它适用于人类,而不是计算机)。有关正确的数据格式的详细信息,请参阅该数据在格式化部分我们对reporducible研究指南。您应该始终尽可能地导入原始输出数据,并避免对数据进行任何“手动”(即非脚本化)修改,尤其是在Excel等程序中,该程序会不时地处理数据(Zeeberg等人(2004年) ))。
在整个研讨会中,我们将使用Wagner等人的数据。(2016),一项研究植物年龄,基因型和环境对芥菜家族多年生草本植物Boechera stricta细菌微生物组的影响的研究。
Wagner等。(2016)发布了他们的原始数据与文章,它可在这里的树妖。这是如何共享原始数据的绝佳示例!
通常有许多函数用于读取表格数据,包括Rread.table和R等基本Rread.csv函数,但我们将使用新readr程序包中的函数,该函数返回小滴而不是data.frames(R中的“表”)。
library(readr)# Loads the readr package so we can use `read_tsv`(加载readr 包,可使用read_tsv )
小贴士是一种data.frame打印效果更好,行为更一致的类型。单击此处下载OTU表。让我们首先读取原始OTU表:
otu_data <- read_tsv("data/otuTable97.txt.bz2")# You might need to change the path to the file
print(otu_data)# You can also enter just `otu_data` to print it
### A tibble: 47,806 x 1,699## OTU_ID M1024P1833 M1551P81 M1551P57 M1551P85 M1551P28 M1551P29 M1551P38 M1551P90 M1551P71
## <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>## 1 1 0 0 0 0 0 0 0 0 0
## 2 2 41 22 4 726 112492 2 413 2 1
## 3 3 67 65 12 13514 1 4 13314 70 5929
## 4 4 3229 13679 1832 951 113 2496 567 2428 2156
## 5 5 1200 92 3530 2008 0 183 2087 292 1058
## 6 6 219 1980 1200 499 1 781 214 2273 171
## 7 7 485 5123 755 4080 443 1278 2193 401 5320
## 8 8 840 7079 3760 22 0 2699 22 2870 32
## 9 9 40 82 91 881 1 449 1121 90 2283
## 10 10 11 79 277 2879 1 0 6811 14 243
## # ... with 47,796 more rows, and 1,689 more variables: M1551P12 <dbl>, M1551P84 <dbl>,
## # M1551P48 <dbl>, M1551P4 <dbl>, M1551P52 <dbl>, M1551P3 <dbl>, M1551P15 <dbl>, M1551P31 <dbl>,
## # M1551P75 <dbl>, M1551P88 <dbl>, …
这是一个大数据集,具有47,806行(OTU)和1,699列(1,698个样本和一个OTU ID)。如果您的计算机无法加载该文件,请不用担心,我们稍后将在研讨会的其余部分中提供一个子集。
在此数据集中,OTU的分类分类位于不同的文件中。该信息本可以作为其他列包含在OTU表中,并且通常包含在其他数据集中。单击此处下载分类学分类表。
tax_data <- read_tsv("data/taxAssignments97.txt")
print(tax_data)# You can also enter `tax_data` to print it
# # A tibble: 47,806 x 8
## `OTU ID` taxonomy Kingdom Phylum Class Order Family Confidence
## <chr> <chr> <chr> <chr> <chr> <chr> <chr> <dbl>
## 1 OTU_1 Unassigned Unassig… Unassi… Unassig… Unassig… Unassign… 1.00
## 2 OTU_10 Root;k__Bacteria;p__Bacteroid… Bacteria Bacter… Sphingo… Sphingo… Sphingob… 1.00
## 3 OTU_100 Root;k__Bacteria;p__Cyanobact… Bacteria Cyanob… Chlorop… Chlorop… NA 1.00
## 4 OTU_1000 Root;k__Bacteria;p__Actinobac… Bacteria Actino… Actinob… Actinom… Actinosy… 0.670
## 5 OTU_10000 Unassigned Unassig… Unassi… Unassig… Unassig… Unassign… 1.00
## 6 OTU_10001 Root;k__Bacteria;p__Chlamydia… Bacteria Chlamy… Chlamyd… Chlamyd… Parachla… 1.00
## 7 OTU_10002 Root;k__Bacteria;p__Proteobac… Bacteria Proteo… Alphapr… NA NA 1.00
## 8 OTU_10003 Unassigned Unassig… Unassi… Unassig… Unassig… Unassign… 1.00
## 9 OTU_10004 Unassigned Unassig… Unassi… Unassig… Unassig… Unassign… 1.00
## 10 OTU_10005 Root;k__Bacteria;p__Cyanobact… Bacteria Cyanob… 4C0d-2 MLE1-12 NA 1.00
## # ... with 47,796 more rows
尽管与大多数数据相比,这些数据的格式非常好,但是仍然存在一些问题。“ OTU ID”列的名称中包含一个空格(因此在后面打勾),这使得在R中使用该名称更加烦人。更重要的是,分类表中的OTU ID前缀为“ OTU_”, OTU表中没有,因此我们必须删除该前缀以使两者匹配。函数sub和gsub用于搜索和替换部分文本;sub仅替换第一个匹配项并gsub替换所有匹配项。一无所有("")可以有效地进行搜索和删除。
tax_data$`OTU ID`<- sub(tax_data$`OTU ID`,# ` are needed because of the space
pattern ="OTU_",replacement ="")
print(tax_data)
### A tibble: 47,806 x 8## `OTU ID` taxonomy Kingdom Phylum Class Order Family Confidence
## <chr> <chr> <chr> <chr> <chr> <chr> <chr> <dbl>## 1 1 Unassigned Unassig… Unassig… Unassig… Unassig… Unassign… 1.00
## 2 10 Root;k__Bacteria;p__Bacteroid… Bacteria Bactero… Sphingo… Sphingo… Sphingob… 1.00
## 3 100 Root;k__Bacteria;p__Cyanobact… Bacteria Cyanoba… Chlorop… Chlorop… NA 1.00
## 4 1000 Root;k__Bacteria;p__Actinobac… Bacteria Actinob… Actinob… Actinom… Actinosy… 0.670
## 5 10000 Unassigned Unassig… Unassig… Unassig… Unassig… Unassign… 1.00
## 6 10001 Root;k__Bacteria;p__Chlamydia… Bacteria Chlamyd… Chlamyd… Chlamyd… Parachla… 1.00
## 7 10002 Root;k__Bacteria;p__Proteobac… Bacteria Proteob… Alphapr… NA NA 1.00
## 8 10003 Unassigned Unassig… Unassig… Unassig… Unassig… Unassign… 1.00
## 9 10004 Unassigned Unassig… Unassig… Unassig… Unassig… Unassign… 1.00
## 10 10005 Root;k__Bacteria;p__Cyanobact… Bacteria Cyanoba… 4C0d-2 MLE1-12 NA 1.00
## # ... with 47,796 more rows
尽管我们可以使用单独的OTU和分类表进行分析,但让我们将它们组合起来可以简化事情。由于行的顺序不同,因此我们需要根据它们的OTU ID组合(也称为“联接”)它们。我们将为此使用dplyr包。
library(dplyr)# Loads the dplyr package so we can use `left_join`(加载dplyr包,可使用left_join)
tax_data$`OTU ID`<- as.character(tax_data$`OTU ID`)# Must be same type for join to work(数据要同一类型才可连接)
otu_data$OTU_ID <- as.character(otu_data$OTU_ID)# Must be same type for join to work
otu_data <- left_join(otu_data, tax_data,by =c("OTU_ID"= "OTU ID"))# identifies cols with shared IDs(共同ID鉴别)
print(otu_data)
## A tibble: 47,806 x 1,706## OTU_ID M1024P1833 M1551P81 M1551P57 M1551P85 M1551P28 M1551P29 M1551P38 M1551P90 M1551P71
## <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>## 1 1 0. 0. 0. 0. 0. 0. 0. 0. 0.
## 2 2 41. 22. 4. 726. 112492. 2. 413. 2. 1.
## 3 3 67. 65. 12. 13514. 1. 4. 13314. 70. 5929.
## 4 4 3229. 13679. 1832. 951. 113. 2496. 567. 2428. 2156.
## 5 5 1200. 92. 3530. 2008. 0. 183. 2087. 292. 1058.
## 6 6 219. 1980. 1200. 499. 1. 781. 214. 2273. 171.
## 7 7 485. 5123. 755. 4080. 443. 1278. 2193. 401. 5320.
## 8 8 840. 7079. 3760. 22. 0. 2699. 22. 2870. 32.
## 9 9 40. 82. 91. 881. 1. 449. 1121. 90. 2283.
## 10 10 11. 79. 277. 2879. 1. 0. 6811. 14. 243.
## # ... with 47,796 more rows, and 1,696 more variables: M1551P12 <dbl>, M1551P84 <dbl>,
## # M1551P48 <dbl>, M1551P4 <dbl>, M1551P52 <dbl>, M1551P3 <dbl>, M1551P15 <dbl>, M1551P31 <dbl>,
## # M1551P75 <dbl>, M1551P88 <dbl>, …
列太多了,所有列都没有显示在打印输出中,但是我们可以通过查看最后10个列名来验证它们是否存在:
tail(colnames(otu_data),n =10)# `tail` returns the last n elements(tail返回最后几个元素)
## [1] "M1958P1043" "M1691P1526" "M1691P1557" "taxonomy" "Kingdom" "Phylum" "Class"
## [8] "Order" "Family" "Confidence"
接下来,加载样本数据。单击此处下载样本数据表。
sample_data <- read_tsv("data/SMD.txt",col_types ="cccccccccccccccc")# each "c" means a column of "character"(每个c指一列字符)
print(sample_data)# You can also enter `sample_data` to print it
### A tibble: 1,698 x 16## SampleID Name Plant_ID Type Experiment Cohort Harvested Age Site Treatment Line Genotype
## <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
## 1 M1024P17… R_026… R_026 root fieldBCMA 2008 2011 3 LTM field 26 ril
## 2 M1024P17… R_073… R_073 root fieldBCMA 2008 2011 3 LTM field 73 ril
## 3 M1024P17… R_088… R_088 root fieldBCMA 2009 2011 2 LTM field 88 ril
## 4 M1024P18… R_156… R_156 root fieldBCMA 2009 2011 2 LTM field 156 ril
## 5 M1955P804 1_A_1… 1_A_1 root ecoGH NA 2011 NA Duke MAHsoil par1… PAR
## 6 M1956P837 1_A_1… 1_A_12 root ecoGH NA 2011 NA Duke MAHsoil mah3… MAH
## 7 M1957P983 1_A_3… 1_A_3 root ecoGH NA 2011 NA Duke MAHsoil silL… SIL
## 8 M1956P845 1_A_4… 1_A_4 root ecoGH NA 2011 NA Duke MAHsoil par1… PAR
## 9 M1957P987 1_A_7… 1_A_7 root ecoGH NA 2011 NA Duke MAHsoil par9… PAR
## 10 M1957P923 1_A_8… 1_A_8 root ecoGH NA 2011 NA Duke MAHsoil mil5… MIL
## # ... with 1,688 more rows, and 4 more variables: Block <chr>, oldPlate <chr>, newPlate <chr>,
## # Analysis <chr>
请注意,其中的示例列数otu_data等于其中的行数,sample_data并且列名称otu_data出现在“ SampleID”列中。这意味着的内容sample_data$SampleID可用于子集OTU表中的列。
转换为taxmap格式
尽管我们的数据现在以R表示,但它的格式不是专门针对社区数量数据的格式;R只知道您有几个大桌子。用于社区(例如微生物组)分析的不同R软件包期望数据采用不同的格式或类别。用编程术语来说,类是定义的存储数据的方式以及一些旨在与该数据交互的功能。当您以这种方式格式化特定数据集时,我们称其为类的对象或“实例”。许多R包实现了自己的类和函数,以将数据转换为它们的格式,而某些包使用其他包中定义的类。对于如何在R中存储按分类法分类的丰度矩阵,有几种选择(例如phyloseq对象),但我们将在此使用taxa包中定义的类。该taxa软件包的目标是提供一种通用的标准方式来处理分配给分类法的任何类型的信息。Taxa提供一组灵活的解析器,只要设置正确,它们就应该能够读取几乎任何格式。您可以taxa在此处阅读有关解析分类学数据的更多信息:https : //github.com/ropensci/taxa#parsing-data。我们附加到丰度矩阵的分类数据具有以下形式:
head(otu_data$taxonomy, 10)
## [1] "Unassigned"
## [2] "Root;k__Bacteria;p__Proteobacteria;c__Alphaproteobacteria;o__Rickettsiales;f__mitochondria"
## [3] "Root;k__Bacteria;p__Proteobacteria;c__Alphaproteobacteria;o__Sphingomonadales;f__Sphingomonadaceae"
## [4] "Root;k__Bacteria;p__Proteobacteria;c__Alphaproteobacteria;o__Rickettsiales;f__mitochondria"
## [5] "Root;k__Bacteria;p__Proteobacteria;c__Alphaproteobacteria;o__Rhizobiales;f__Rhizobiaceae"
## [6] "Root;k__Bacteria;p__Actinobacteria;c__Actinobacteria;o__Actinomycetales;f__Kineosporiaceae"
## [7] "Root;k__Bacteria;p__Cyanobacteria;c__Chloroplast;o__Streptophyta;f__"
## [8] "Root;k__Bacteria;p__Proteobacteria;c__Alphaproteobacteria;o__Rhizobiales;f__Bradyrhizobiaceae"
## [9] "Root;k__Bacteria;p__Proteobacteria;c__Gammaproteobacteria;o__Pseudomonadales;f__Pseudomonadaceae"
## [10] "Root;k__Bacteria;p__Bacteroidetes;c__Sphingobacteriia;o__Sphingobacteriales;f__Sphingobacteriaceae"
请注意,格式存在一些奇怪的方面,可能使其难以解析:
有些分类单元具有等级(例如 “k__Bacteria“)),有些分类则没有(例如“Unassigned”和“root”)。一些分类单元具有等级,但没有名称(例如“ f__”)。
如果我们仅将等级视为分类单元名称的一部分,那么它很容易解析:
library(taxa)
obj <- parse_tax_data(otu_data,
class_cols = "taxonomy", # The column in the input table(输入表中的列)
class_sep = ";") # What each taxon is seperated by(每个分类单元由什么分开)
print(obj)
## <Taxmap>
## 1558 taxa: aab. Unassigned, aac. Root ... chx. f__Methanospirillaceae, chy. f__
## 1558 edges: NA->aab, NA->aac, aac->aad, aac->aae ... bel->chw, ays->chx, bem->chy
## 1 data sets:
## tax_data:
## # A tibble: 47,806 x 1,707
## taxon_id OTU_ID M1024P1833 M1551P81 M1551P57 M1551P85 M1551P28 M1551P29 M1551P38
## <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 aab 1 0. 0. 0. 0. 0. 0. 0.
## 2 ben 2 41. 22. 4. 726. 112492. 2. 413.
## 3 beo 3 67. 65. 12. 13514. 1. 4. 13314.
## # ... with 4.78e+04 more rows, and 1,698 more variables: M1551P90 <dbl>,
## # M1551P71 <dbl>, M1551P12 <dbl>, M1551P84 <dbl>, M1551P48 <dbl>, M1551P4 <dbl>,
## # M1551P52 <dbl>, M1551P3 <dbl>, M1551P15 <dbl>, M1551P31 <dbl>, …
## 0 functions:
上面是taxmap对象的输出。第一行告诉我们,OTU已分配给1,558个唯一分类单元,并列出了它们的ID和名称。这些分类单元ID是在转换为taxmap格式时自动生成的,并且不在原始数据集中。第二行描述了分类单元在树中的相互关系。请注意,我们的原始数据现在如何在此对象内:
print(obj$data$tax_data)
### A tibble: 47,806 x 1,707## taxon_id OTU_ID M1024P1833 M1551P81 M1551P57 M1551P85 M1551P28 M1551P29 M1551P38 M1551P90
## <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>## 1 aab 1 0. 0. 0. 0. 0. 0. 0. 0.
## 2 ben 2 41. 22. 4. 726. 112492. 2. 413. 2.
## 3 beo 3 67. 65. 12. 13514. 1. 4. 13314. 70.
## 4 ben 4 3229. 13679. 1832. 951. 113. 2496. 567. 2428.
## 5 bep 5 1200. 92. 3530. 2008. 0. 183. 2087. 292.
## 6 beq 6 219. 1980. 1200. 499. 1. 781. 214. 2273.
## 7 ber 7 485. 5123. 755. 4080. 443. 1278. 2193. 401.
## 8 bes 8 840. 7079. 3760. 22. 0. 2699. 22. 2870.
## 9 bet 9 40. 82. 91. 881. 1. 449. 1121. 90.
## 10 beu 10 11. 79. 277. 2879. 1. 0. 6811. 14.
## # ... with 47,796 more rows, and 1,697 more variables: M1551P71 <dbl>, M1551P12 <dbl>,
## # M1551P84 <dbl>, M1551P48 <dbl>, M1551P4 <dbl>, M1551P52 <dbl>, M1551P3 <dbl>, M1551P15 <dbl>,
## # M1551P31 <dbl>, M1551P75 <dbl>, …
obj$data是任意的,用户定义的数据集的列表。这些数据集可以命名为任何名称,并且可以是任何R对象,例如list,vectors或table。这与phyloseq对象具有不同的对象,对象具有固定数量的预定义格式的数据集,因为对象的重点taxa通常是分类phyloseq数据,尤其是微生物组数据。请注意,我们的数据集现在具有“ taxon_id”列,该列将表中的行与分类法中的分类单元相关联。本专栏对于taxa了解如何处理这些数据集的操作功能至关重要,我们将在后面进行演示。
如果要在解析时拆分等级信息,可以使用正则表达式(也称为“ regex”)来指定每个分类单元的哪一部分是等级,哪一部分是名称。如果您不熟悉使用正则表达式,一开始可能很难理解,但是这是一项非常有用的技能,因此值得学习。大多数正则表达式由一系列“要匹配的内容”后跟“要匹配多少次”组成。一个与分类单元名称模式匹配的正则表达式是^[a-z]{0,1}_{0,2}.*$。这看似令人生畏,但我们可以将其分解为可以理解的部分:
在^和$分别代表文本的开始和结束。如果这些内容不存在,则该模式可能仅与文本的一部分匹配。
方括号(例如[a-z])指定了可以匹配的字符范围。同样,.手段匹配任何字符。
花括号(例如{0,1})的内容表示前面的样式可以匹配的时间。同样,*均值等于或大于0。例如,正则表达式的一部分^[a-z]{0,1}的装置“相匹配的字符a通过z使得在字符串的开始出现零本或一个次”。
不是特殊正则表达式字符的任何文本(例如[和.)都将匹配自身,因此_匹配_文本中的a 。要匹配的字符一样[在你与“逃离”他们的文字\\(如\\[)。
整个正则表达式在通用英语中含义如下:
“从字符串的开头,(^)匹配“ a”和“ z”之间的任何字符([a-z])零或一次({0,1}),然后是下划线(_)出现在零至2倍({0,2})之间,然后是任何字符(.)出现零次或多次(*),然后是文字结尾($)。”
我们可以添加括号以指定模式的哪些部分在一起;这些在正则表达式行话中称为捕获组。这些不会改变将要匹配的内容。他们只是定义了模式的不同部分。在这种情况下,我们对分类单元等级(由匹配([a-z]{0,1}))和分类名称(由匹配)感兴趣(.*)。
包中的parse_tax_data函数taxa使用带有捕获组的正则表达式来隔离所需的信息。对于正则表达式(也称为“ regex”)中的每个捕获组,将为class_key选项提供一个值,指定该组是什么(例如,分类单元名称)。将所有这些放在一起,我们可以像这样读取数据:
obj <- parse_tax_data(otu_data,
class_cols = "taxonomy",
class_sep = ";",
class_regex = "^([a-z]{0,1})_{0,2}(.*)$",
class_key = c("tax_rank" = "taxon_rank", "name" = "taxon_name"))
print(obj)
## ## 1558 taxa:aab. Unassigned, aac. Root ... chx. Methanospirillaceae, chy.
## 1558 edges: NA->aab, NA->aac, aac->aad, aac->aae ... bel->chw, ays->chx, bem->chy## 2 data sets:
## tax_data:
## # A tibble: 47,806 x 1,707## taxon_id OTU_ID M1024P1833 M1551P81 M1551P57 M1551P85 M1551P28 M1551P29 M1551P38
## <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>## 1 aab 1 0. 0. 0. 0. 0. 0. 0.
## 2 ben 2 41. 22. 4. 726. 112492. 2. 413.
## 3 beo 3 67. 65. 12. 13514. 1. 4. 13314.
## # ... with 4.78e+04 more rows, and 1,698 more variables: M1551P90 <dbl>,
## # M1551P71 <dbl>, M1551P12 <dbl>, M1551P84 <dbl>, M1551P48 <dbl>, M1551P4 <dbl>,
## # M1551P52 <dbl>, M1551P3 <dbl>, M1551P15 <dbl>, M1551P31 <dbl>, …
## class_data:
## # A tibble: 216,417 x 5## taxon_id input_index tax_rank name regex_match
## <chr> <int> <chr> <chr> <chr> ## 1 aab 1 "" Unassigned Unassigned
## 2 aac 2 "" Root Root
## 3 aad 2 k Bacteria k__Bacteria
## # ... with 2.164e+05 more rows
## 0 functions:
请注意分类单元名称不再具有等级信息:
head(taxon_names(obj))
## aab aac aad aae aaf
## "Unassigned" "Root" "Bacteria" "Archaea" "Proteobacteria"
## aag
## "Actinobacteria"
相反,排名信息(以及任何其他捕获组内容)在单独的数据集中:
obj$data$class_data
## # A tibble: 216,417 x 5
## taxon_id input_index tax_rank name regex_match
## <chr> <int> <chr> <chr> <chr>
## 1 aab 1 "" Unassigned Unassigned
## 2 aac 2 "" Root Root
## 3 aad 2 k Bacteria k__Bacteria
## 4 aaf 2 p Proteobacteria p__Proteobacteria
## 5 add 2 c Alphaproteobacteria c__Alphaproteobacteria
## 6 amg 2 o Rickettsiales o__Rickettsiales
## 7 ben 2 f mitochondria f__mitochondria
## 8 aac 3 "" Root Root
## 9 aad 3 k Bacteria k__Bacteria
## 10 aaf 3 p Proteobacteria p__Proteobacteria
## # ... with 216,407 more rows
但是,也可以使用以下taxon_ranks功能访问等级:
head(taxon_ranks(obj))
## aab aac aad aae aaf aag
## "" "" "k" "k" "p" "p"
因此,我们实际上并不需要“ class_data”表,因此让我们摆脱它:
obj$data$class_data <- NULL
让我们也将“ tax_data”表重命名为更有用的信息:
names(obj$data) <- "otu_counts"
print(obj)
## ## 1558 taxa:aab. Unassigned, aac. Root ... chx. Methanospirillaceae, chy.
## 1558 edges: NA->aab, NA->aac, aac->aad, aac->aae ... bel->chw, ays->chx, bem->chy## 1 data sets:
## otu_counts:
## # A tibble: 47,806 x 1,707## taxon_id OTU_ID M1024P1833 M1551P81 M1551P57 M1551P85 M1551P28 M1551P29 M1551P38
## <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>## 1 aab 1 0. 0. 0. 0. 0. 0. 0.
## 2 ben 2 41. 22. 4. 726. 112492. 2. 413.
## 3 beo 3 67. 65. 12. 13514. 1. 4. 13314.
## # ... with 4.78e+04 more rows, and 1,698 more variables: M1551P90 <dbl>,
## # M1551P71 <dbl>, M1551P12 <dbl>, M1551P84 <dbl>, M1551P48 <dbl>, M1551P4 <dbl>,
## # M1551P52 <dbl>, M1551P3 <dbl>, M1551P15 <dbl>, M1551P31 <dbl>, …
## 0 functions:
我们可以根据需要命名表或其他信息obj$data。obj$data是一个标准list,这意味着可以放入任何数量的任何类型的东西。