如何填补一系列字符串中的空白?

时间:2019-02-25 08:51:09

标签: r

我遇到了一个问题,其中程序包检索的生物分类信息(关于物种的信息)的长度不相同。因此,该函数将输出存储在一个列表中,该列表包含2行和各种列数的表(分类行为1行,信息本身为1行):

taxo.spA <- data.frame(name=c("Animalia", "Arthropoda", "Chelicerata", 
                                 "Arachnida", "Acari"), 
                       rank=c("Kingdom", "Phylum", "Subphylum", "Class", 
                              "Subclass"))

taxo.spB <- data.frame(name=c("Animalia", "Chordata", "Vertebrata", 
                               "Gnathostomata", "Actinopterygii", "Perciformes", 
                               "Trachinoidei", "Ammodytidae", "Ammodytes", 
                               "Ammodytes tobianus"),
                       rank=c("Kingdom", "Phylum", "Subphylum", "Superclass", 
                              "Class", "Order", "Suborder", "Family", "Genus", 
                              "Species"))

我想得到一个表,其行列为列,名称为行。 主要问题是,分类法通常在等级上有所不同,某些分类单元无法解析到物种级别(如Acari),或者如果解析,则分类可能会有所不同(没有超类),因此您无法进行绑定或rbind这些表(=不同的列数或行数)。

但是,生物分类等级遵循层次结构,因此我一直在尝试重新构建这一系列等级(王国到种或亚种)。 我不知道什么是最好的方法?是否有一个包/函数可以找到两个字符串之间的匹配项以及在其中插入丢失内容的位置?


例如:

ranks1 <- c("Kingdom", "Phylum", "Subphylum", "Class")
ranks2 <- c("Kingdom", "Phylum", "Subphylum", "Superclass", "Class", "Order")

该功能将确定Kingdom:Subphylum和Class是相同的。而且Subphylum和Class围绕超类,因此可以在Subphylum和Class之间插入Superclass。最后,该Order丢失了,应该在Class之后的右侧:

“王国”,“ Phylum”,“ Subphylum”,“超类”,“类”,“订单”

最终,我正在编写的函数将构建一个具有n列(=最长的分类法)和S行(分类单元的数量)的data.frame,并以正确的方式填充每个分类单元上的分类信息列,其余为NA。

desired.output <- data.frame(rbind(c("Animalia", "Arthropoda", "Chelicerata", 
                                     NA, "Arachnida", "Acari", NA), 
                                   c("Animalia", "Chordata", "Vertebrata", 
                                     "Gnathostomata", "Actinopterygii", NA, 
                                     "Perciformes")))

names(desired.output) <- c("Kingdom", "Phylum", "Subphylum", "Superclass", 
                           "Class", "Subclass", "Order")

我试图从我拥有的最完整的信息之一入手,并与其他分类单元进行比较。我玩过setdiff(),intersect(),%in%;并试图找到共有的东西,什么仅属于两个字符串之一,然后重建它,但我不确定这是最好的方法吗?

有什么想法吗?有建议吗?

我将数据集保留为数据框(尽管现在更多为矩阵),因为稍后将其与其他数据集合并。


下面的编辑/答案

首先,感谢您的帮助。我从答案中激发了自己,并设法使它起作用。

主要问题是列表(1)中包含的表没有相同数量的行,(2)行中可能包含不同的信息(分类中可能会跳过某些排名),这使得合并所有内容变得困难放在一张桌子里。

但是,分类法具有这种树状的层次结构,我可以使用它来查找那些等级如何一起分支。 我如何解决这个问题:

我使用信息最解析的生物作为参考(=最高等级数),然后获取每个等级列表(等级向量),并发现与该最高解析度向量之间的差异。 然后,我通过查看层次结构中高于和低于其的排名以及在我的参考中匹配的位置来寻找那些缺失的排名的位置。

可能有四种情况(最高等级在左边,最低在右边):

  • 不匹配:我无法将该排名放入分类法中(尚未)
  • 2个匹配项:我可以将丢失的信息放在两个匹配项之间 参考
  • 左侧有1个比赛:我可以将其放在比赛之后
  • 右侧有1个比赛:我可以将其放在比赛之前

我遍历缺少的等级,并依次增加等级,直到数据集中所有可能的等级都包含在向量中:我使用函数append()在由通用等级的位置定义的特定位置之后依次添加缺少的等级在参考分类法和其他分类法之间。

最后,我将此向量用作最终表的列名,并在表中填充了分类单元信息(请参见下文)。 也许不是最好的方法,但应该在分类法上保持一致。

非常感谢! (P.S.最终完成应做的事情时感觉很好)

Final table

2 个答案:

答案 0 :(得分:1)

您首先可以定义一个函数,将taxo*转换为不完整的结束格式。

myTransform <- function(x) {
  tr <- t(x[2:1])
  colnames(tr) <- make.names(tr[1, ], unique=TRUE)  # `make.names()` to get unique column names
  return(as.data.frame(t(tr[-1, ])))
}

然后将所有taxo*放入列表l。例如。 mget()(如果它们已加载到工作空间中)。

l <- lapply(mget(ls(pattern="taxo")), myTransform)

(这与l <- lapply(list(taxo.spA, taxo.spB), myTransform)的操作基本相同,但是假定您有一大堆taxo*。)

在列表中的数据帧中添加id列是有意义的。

l <- l <- lapply(1:length(l), function(x) cbind(id=names(l)[x], l[[x]]))

现在运行merge()并包装到Reduce()中,如下所示:

out <- Reduce(function(...) merge(..., all=TRUE), l)

给予

> out
        id  Kingdom     Phylum   Subphylum          Class Subclass
1 taxo.spA Animalia Arthropoda Chelicerata      Arachnida    Acari
2 taxo.spB Animalia   Chordata  Vertebrata Actinopterygii     <NA>
3 taxo.spC Animalia Arthropoda Chelicerata      Arachnida    Acari
     Superclass       Order     Suborder      Family     Genus
1          <NA>        <NA>         <NA>        <NA>      <NA>
2 Gnathostomata Perciformes Trachinoidei Ammodytidae Ammodytes
3          <NA>        <NA>         <NA>        <NA>      <NA>
             Species Subclass.1
1               <NA>       <NA>
2 Ammodytes tobianus       <NA>
3               <NA>  Something
1               <NA>       <NA>
2 Ammodytes tobianus       <NA>
3               <NA>  Something

其他数据 (以模拟重复的列)

taxo.spC <- structure(list(name = structure(c(2L, 4L, 5L, 3L, 1L, 6L), .Label = c("Acari", 
"Animalia", "Arachnida", "Arthropoda", "Chelicerata", "Something"
), class = "factor"), rank = structure(c(2L, 3L, 5L, 1L, 4L, 
4L), .Label = c("Class", "Kingdom", "Phylum", "Subclass", "Subphylum"
), class = "factor")), row.names = c(NA, -6L), class = "data.frame")

答案 1 :(得分:0)

怎么样呢?

ionic serve

结果将是:

Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36