提问者:小点点

将字符串子集为不均匀列表并从列表中逻辑传播data. frame


我花了很多时间试图解决这个问题,但没有成功。

我有一个data. frame,其中包含一个包含可变长度字符串的列。data.frame如下所示:

Taxa <- as.character(c("cellularorganisms(norank)_Bacteria(superkingdom)_Actinobacteria(phylum)","cellularorganisms(norank)_Bacteria(superkingdom)_Proteobacteria(phylum)_Gammaproteobacteria(class)_Enterobacteriales(order)_Enterobacteriaceae(family)","cellularorganisms(norank)_Bacteria(superkingdom)_Proteobacteria(phylum)_Gammaproteobacteria(class)_Enterobacteriales(order)","cellularorganisms(norank)_Bacteria(superkingdom)_Proteobacteria(phylum)_Gammaproteobacteria(class)_Enterobacteriales(order)_Enterobacteriaceae(family)_Klebsiella(genus)","cellularorganisms(norank)_Bacteria(superkingdom)_Proteobacteria(phylum)_Gammaproteobacteria(class)_Enterobacteriales(order)_Enterobacteriaceae(family)_Klebsiella(genus)_Klebsiellapneumoniae(species)","cellularorganisms(norank)_Bacteria(superkingdom)_Firmicutes(phylum)_Clostridia(class)_Clostridiales(order)","cellularorganisms(norank)_Bacteria(superkingdom)_Firmicutes(phylum)_Clostridia(class)","cellularorganisms(norank)_Bacteria(superkingdom)_Firmicutes(phylum)_Clostridia(class)_Clostridiales(order)_Clostridiaceae(family)","cellularorganisms(norank)_Bacteria(superkingdom)_Firmicutes(phylum)_Clostridia(class)_Clostridiales(order)_Clostridiaceae(family)_Clostridium(genus)","cellularorganisms(norank)_Bacteria(superkingdom)_Firmicutes(phylum)_Clostridia(class)_Clostridiales(order)_Clostridiaceae(family)_Clostridium(genus)_Clostridiumbotulinum(species)","cellularorganisms(norank)_Bacteria(superkingdom)_Firmicutes(phylum)_Clostridia(class)_Clostridiales(order)_Clostridiaceae(family)_Clostridium(genus)_Clostridiumbotulinum(species)_ClostridiumbotulinumCDC66177(strain)","cellularorganisms(norank)_Bacteria(superkingdom)_Actinobacteria(phylum)_Actinobacteria(class)_Actinobacteridae(subclass)_Actinomycetales(order)_Micrococcineae(suborder)","cellularorganisms(norank)_Bacteria(superkingdom)_Actinobacteria(phylum)_Actinobacteria(class)_Actinobacteridae(subclass)_Actinomycetales(order)_Micrococcineae(suborder)_Microbacteriaceae(family)","cellularorganisms(norank)_Bacteria(superkingdom)_Actinobacteria(phylum)_Actinobacteria(class)_Actinobacteridae(subclass)_Actinomycetales(order)_Micrococcineae(suborder)_Microbacteriaceae(family)_Microbacterium(genus)","cellularorganisms(norank)_Bacteria(superkingdom)_Actinobacteria(phylum)_Actinobacteria(class)_Actinobacteridae(subclass)_Actinomycetales(order)_Micrococcineae(suborder)_Microbacteriaceae(family)_Microbacterium(genus)_Microbacteriumlaevaniformans(species)_MicrobacteriumlaevaniformansOR221(strain)"))
Percent <- c("0.000400","0.006800","0.005034","0.001760","0.000000","0.000000","0.344400","0.000000","0.000000","0.000000","0.006500","0.002819","0.000487","0.000000","0.001090")
Test <- data.frame(Percent, Taxa)
Test$Taxa <- as.character(Test$Taxa)

我可以将下划线上的这些字符串子集为不相等长度的列表:

NewDF <- strsplit(Test$Taxa, "_", fixed=TRUE)

但是我不知道如何将这个解析的输出格式化为可用的结构。

每个解析的部分有两个组件,一个描述符和一个分类级别(即细菌(超级王国)是描述符细菌和分类级别的超级王国。

我想做的是获取这个解析后的输出,并填充一个具有以下列标题(norank、超级王国、门、类、顺序、科、属、种、株)的data. frame。输出需要跳过上面列表中未包含的分类级别(例如,在class和order之间有具有分类级别子类的行,我需要删除子类)。

此外,如果一行停在特定的分类级别并且仍有未填充的列,则应将它们设置为NA(即第一行以门结束,因此类、顺序、家族等应为NA)。

最终输出应如下所示:

                      norank           superkingdom                 phylum                      class                    order                     family                 genus                               species                                    strain
1  cellularorganisms(norank) Bacteria(superkingdom) Actinobacteria(phylum)                       <NA>                     <NA>                       <NA>                  <NA>                                  <NA>                                      <NA>
2  cellularorganisms(norank) Bacteria(superkingdom) Proteobacteria(phylum) Gammaproteobacteria(class) Enterobacteriales(order) Enterobacteriaceae(family)                  <NA>                                  <NA>                                      <NA>
3  cellularorganisms(norank) Bacteria(superkingdom) Proteobacteria(phylum) Gammaproteobacteria(class) Enterobacteriales(order)                       <NA>                  <NA>                                  <NA>                                      <NA>
4  cellularorganisms(norank) Bacteria(superkingdom) Proteobacteria(phylum) Gammaproteobacteria(class) Enterobacteriales(order) Enterobacteriaceae(family)     Klebsiella(genus)                                                                            <NA>
5  cellularorganisms(norank) Bacteria(superkingdom) Proteobacteria(phylum) Gammaproteobacteria(class) Enterobacteriales(order) Enterobacteriaceae(family)     Klebsiella(genus)         Klebsiellapneumoniae(species)                                      <NA>
6  cellularorganisms(norank) Bacteria(superkingdom)     Firmicutes(phylum)          Clostridia(class)     Clostridiales(order)                       <NA>                  <NA>                                  <NA>                                      <NA>
7  cellularorganisms(norank) Bacteria(superkingdom)     Firmicutes(phylum)          Clostridia(class)                     <NA>                       <NA>                  <NA>                                  <NA>                                      <NA>
8  cellularorganisms(norank) Bacteria(superkingdom)     Firmicutes(phylum)          Clostridia(class)     Clostridiales(order)     Clostridiaceae(family)                  <NA>                                  <NA>                                      <NA>
9  cellularorganisms(norank) Bacteria(superkingdom)     Firmicutes(phylum)          Clostridia(class)     Clostridiales(order)     Clostridiaceae(family)    Clostridium(genus)                                  <NA>                                      <NA>
10 cellularorganisms(norank) Bacteria(superkingdom)     Firmicutes(phylum)          Clostridia(class)     Clostridiales(order)     Clostridiaceae(family)    Clostridium(genus)         Clostridiumbotulinum(species)                                      <NA>
11 cellularorganisms(norank) Bacteria(superkingdom)     Firmicutes(phylum)          Clostridia(class)     Clostridiales(order)     Clostridiaceae(family)    Clostridium(genus)         Clostridiumbotulinum(species)      ClostridiumbotulinumCDC66177(strain)
12 cellularorganisms(norank) Bacteria(superkingdom) Actinobacteria(phylum)      Actinobacteria(class)   Actinomycetales(order)                       <NA>                  <NA>                                  <NA>                                      <NA>
13 cellularorganisms(norank) Bacteria(superkingdom) Actinobacteria(phylum)      Actinobacteria(class)   Actinomycetales(order)  Microbacteriaceae(family)                  <NA>                                  <NA>                                      <NA>
14 cellularorganisms(norank) Bacteria(superkingdom) Actinobacteria(phylum)      Actinobacteria(class)   Actinomycetales(order)  Microbacteriaceae(family) Microbacterium(genus)                                  <NA>                                      <NA>
15 cellularorganisms(norank) Bacteria(superkingdom) Actinobacteria(phylum)      Actinobacteria(class)   Actinomycetales(order)  Microbacteriaceae(family) Microbacterium(genus) Microbacteriumlaevaniformans(species) MicrobacteriumlaevaniformansOR221(strain)

共1个答案

匿名用户

您可以尝试通过将小data. frame列表编译成一个df来做到这一点

library(dplyr)

NewDF <- 
  lapply(strsplit(Test$Taxa, "_", fixed=TRUE),
         function(x)
         {
           vars <- lapply(x, function(y)
           {
             m <- regexec("\\((.+?)\\)",y)
             regmatches(y,m)[[1]][2]
           })
           vals <-  as.list( x )
           names(vals) <- unlist(vars)
           data.frame( vals, 
                       stringsAsFactors = FALSE )
         })  %>% rbind_all

这给了我你想要的结果(也有好看的变量名)