R - 不规则元数据;从大型单列创建 df
R - Irregular metadata; create df from large single column
这个标题并没有真正反映我的问题,因为可能有几种方法可以给这只猫剥皮。但我选择了一种方法并采用了它。这就是我正在使用的:
我使用界面上的 "Send to:" 选项在 NCBI 数据库中提取了特定 study 的所有元数据,并下载了一个 .txt 文件。
我总共有大约 23k 个样本,每个样本都有多达 609 个独特的问题和答案,当以 .csv 格式读取时,问卷总计 8M+ obs of 1 variable。令我沮丧的是,元数据是不规则的。一些样本有 140 个关联的 key/value 对。其他人有 492。我在下面包含了一个 header 示例。
1: qiita_sid_10317:10317.BLANK1.6H.GUELPH
Identifiers: BioSample: SAMEA4790059; SRA: ERS2609990
Organism: metagenome
Attributes:
/Alias="qiita_sid_10317:10317.BLANK1.6H.GUELPH"
/description="American Gut control"
/ENA checklist="ERC000011"
/INSDC center alias="UCSDMI"
/INSDC center name="University of California San Diego Microbiome Initiative"
/INSDC first public="2018-07-13T17:03:10Z"
/INSDC last update="2018-07-13T14:50:03Z"
/INSDC status="public"
/SRA accession="ERS2609990"
我尝试过(包括但不限于):
- 读取 .txt 文件(添加定界符没有任何影响,我在这里遗漏了什么吗?)
- 我尝试使用各种分隔符读取数据
- 我什至删除了 Sublime Text 中的 header 数据,只留下 "Attributes:" 和“/”分隔的 key/value 对,以便以这种方式弄乱列
- 我拆分了在 col1 中找到所有唯一值的列,以便从头开始创建 df,等等。
似乎无法通过清洁步骤:
samples <- read.csv("~/biosample_result_full.txt")
samples_split <- cSplit(samples, splitCols = sample$Colname, sep = "=")
samples_split$Attributes_1 <- gsub(" ", "_", samples_split$Attributes_1)
questions <- unique(samples_split$Attributes_1)
理想情况下,每个样本和关联的元数据都将转换为行,每个 "Attribute"/问题作为列名。
非常感谢任何帮助。
我看到您链接到的网站允许选择将数据导出到 xml。我强烈建议这样做。 R 可以 hande/parse xml-files very efficient.
当我从该站点下载前三个结果到文件 biosample_result.xml
时,使用 xml2
-package
很容易处理
library( xml2 )
library( magrittr )
doc <- read_xml( "./biosample_result.xml")
#gret all BioSample nodes
BioSample.Nodes <- xml_find_all( doc, "//BioSample")
#build a data.frame
data.frame(
sample_name = xml_find_first( BioSample.Nodes , ".//Id[@db='SRA']") %>% xml_text(),
stringsAsFactors = FALSE )
# sample_name
# 1 ERS2609990
# 2 ERS2609989
# 3 ERS2609988
因此,如果您可以使用 XML,您只需要使用正确的 xpath 语法来将您需要的 data/nodes 放入您想要的列中...
在上面的示例中,我(从每个 BioSample 节点)提取了属性 db
等于 SRA
的第一个 ID 节点,并将结果存储在 co0lumn sample_name
.
仍然假设您可以使用 xml-数据。
如果您正在将所有属性锁定到一个 df 中,则需要 purrr
中的函数,因此只需加载整个 tidyverse
library( tidyverse )
df <- xml_find_all( doc, "//BioSample") %>%
map_df(~{
set_names(
xml_find_all(.x, ".//Attribute") %>% xml_text(),
xml_find_all(.x, ".//Attribute") %>% xml_attr( "attribute_name" )
) %>%
as.list() %>%
flatten_df()
})
会产生这样的 df
这个标题并没有真正反映我的问题,因为可能有几种方法可以给这只猫剥皮。但我选择了一种方法并采用了它。这就是我正在使用的:
我使用界面上的 "Send to:" 选项在 NCBI 数据库中提取了特定 study 的所有元数据,并下载了一个 .txt 文件。
我总共有大约 23k 个样本,每个样本都有多达 609 个独特的问题和答案,当以 .csv 格式读取时,问卷总计 8M+ obs of 1 variable。令我沮丧的是,元数据是不规则的。一些样本有 140 个关联的 key/value 对。其他人有 492。我在下面包含了一个 header 示例。
1: qiita_sid_10317:10317.BLANK1.6H.GUELPH
Identifiers: BioSample: SAMEA4790059; SRA: ERS2609990
Organism: metagenome
Attributes:
/Alias="qiita_sid_10317:10317.BLANK1.6H.GUELPH"
/description="American Gut control"
/ENA checklist="ERC000011"
/INSDC center alias="UCSDMI"
/INSDC center name="University of California San Diego Microbiome Initiative"
/INSDC first public="2018-07-13T17:03:10Z"
/INSDC last update="2018-07-13T14:50:03Z"
/INSDC status="public"
/SRA accession="ERS2609990"
我尝试过(包括但不限于):
- 读取 .txt 文件(添加定界符没有任何影响,我在这里遗漏了什么吗?)
- 我尝试使用各种分隔符读取数据
- 我什至删除了 Sublime Text 中的 header 数据,只留下 "Attributes:" 和“/”分隔的 key/value 对,以便以这种方式弄乱列
- 我拆分了在 col1 中找到所有唯一值的列,以便从头开始创建 df,等等。
似乎无法通过清洁步骤:
samples <- read.csv("~/biosample_result_full.txt")
samples_split <- cSplit(samples, splitCols = sample$Colname, sep = "=")
samples_split$Attributes_1 <- gsub(" ", "_", samples_split$Attributes_1)
questions <- unique(samples_split$Attributes_1)
理想情况下,每个样本和关联的元数据都将转换为行,每个 "Attribute"/问题作为列名。
非常感谢任何帮助。
我看到您链接到的网站允许选择将数据导出到 xml。我强烈建议这样做。 R 可以 hande/parse xml-files very efficient.
当我从该站点下载前三个结果到文件 biosample_result.xml
时,使用 xml2
-package
library( xml2 )
library( magrittr )
doc <- read_xml( "./biosample_result.xml")
#gret all BioSample nodes
BioSample.Nodes <- xml_find_all( doc, "//BioSample")
#build a data.frame
data.frame(
sample_name = xml_find_first( BioSample.Nodes , ".//Id[@db='SRA']") %>% xml_text(),
stringsAsFactors = FALSE )
# sample_name
# 1 ERS2609990
# 2 ERS2609989
# 3 ERS2609988
因此,如果您可以使用 XML,您只需要使用正确的 xpath 语法来将您需要的 data/nodes 放入您想要的列中...
在上面的示例中,我(从每个 BioSample 节点)提取了属性 db
等于 SRA
的第一个 ID 节点,并将结果存储在 co0lumn sample_name
.
仍然假设您可以使用 xml-数据。
如果您正在将所有属性锁定到一个 df 中,则需要 purrr
中的函数,因此只需加载整个 tidyverse
library( tidyverse )
df <- xml_find_all( doc, "//BioSample") %>%
map_df(~{
set_names(
xml_find_all(.x, ".//Attribute") %>% xml_text(),
xml_find_all(.x, ".//Attribute") %>% xml_attr( "attribute_name" )
) %>%
as.list() %>%
flatten_df()
})
会产生这样的 df