比较复杂结构列表

时间:2019-02-04 20:17:19

标签: r algorithm comparison phylogeny

我有两个复杂结构的列表(每个列表都是一个包含系统发育树的multiPhylo对象),我想找出第一个元素的每个元素在第二个元素中出现多少次。非常简单,但是由于某些原因,我的代码返回了错误的结果。

library(devtools)
install_github('santiagosnchez/rBt')
library(rBt)

beast_output <- read.annot.beast('strict_BD_starBEAST_logcomb.species.trees')
beast_output_rooted <- root(beast_output, c('taxon_A', 'taxon_B')) # length == 20,000
unique_multiphylo <- unique.multiPhylo(beast_output_rooted) # length == 130

count <- function(item, list) {
  total = 0
  for (i in 1:length(list)) {
    if (all.equal.phylo(item, list[[i]])) {
      total = total + 1
    }
  }
  return(total)
}

result <- data.frame(un_tr = rep(0, 130), count = rep(0, 130))
for (i in 1:length(unique_multiphylo)) {
  result[i, ] <- c(i, count(unique_multiphylo[[i]], beast_output_rooted))
}

函数all.equal.phylo()接受两个系统对象,如果相同,则返回TRUE。参见docs。函数count()获取一个项目和一个列表,然后使用all.equal.phylo()返回该项目出现在列表中的次数。

问题是函数count()在大多数情况下返回0。这应该是不可能的,因为列表unique_multiphylobeast_output_rooted的子列表,这意味着count()至少应返回1。

我的代码有什么问题?我该如何纠正呢?非常感谢您的帮助!

编辑:这是一个可复制的示例:

install.packages('ape')
library(ape)

set.seed(42)
trees <- lapply(rep(c(10, 25, 50, 100), 3), rtree) # length == 12
class(trees) <- 'multiPhylo'
unique_multiphylo <- unique.multiPhylo(trees) # length == 12

count <- function(item, list) {
  total = 0
  for (i in 1:length(list)) {
    if (all.equal.phylo(item, list[[i]])) {
      total = total + 1
    }
  }
  return(total)
}

result <- data.frame(un_tr = rep(0, 12), count = rep(0, 12))
for (i in 1:length(unique_multiphylo)) {
  result[i, ] <- c(i, count(unique_multiphylo[[i]], trees))
}

但是,这些模拟数据似乎工作得很好……

2 个答案:

答案 0 :(得分:2)

我终于设法获得了适当的结果。在功能all.equal.phylo()中,我需要将参数use.edge.length设置为FALSE,以便仅比较系统发育树的topologies

这是我的代码:

(我更改了几个变量的名称,以使我想做的事情更清楚)

install.packages('devtools')
library(devtools)
install_github('santiagosnchez/rBt')
library(rBt)

beast_output <- read.annot.beast('beast_output.trees')
beast_output_rooted <- root.multiPhylo(beast_output, c('taxon_A', 'taxon_B'))
unique_topologies <- unique.multiPhylo(beast_output_rooted)

count <- function(item, list) {
  total = 0
  for (i in 1:length(list)) {
    if (all.equal.phylo(item, list[[i]], use.edge.length = FALSE)) {
      total = total + 1
    }
  }
  return(total)
}

result <- data.frame(unique_topology = rep(0, length(unique_topologies)),
                     count = rep(0, length(unique_topologies)))
for (i in 1:length(unique_topologies)) {
  result[i, ] <- c(i, count(unique_topologies[[i]], beast_output_rooted))
}

result$percentage <- ((result$count/length(beast_output_rooted))*100)

答案 1 :(得分:1)

对于您的问题,有一个更短的解决方案:

table( attr(unique_multiphylo, "old.index") )

因为unique_multiphylo包含一个属性,其中包含您要关注的信息(请参阅?unique.multiPhylo)。