Я попытался распараллелить ape::dist_topo()
, функцию для вычисления расстояний между необращенными деревьями.
Обычно функция работает следующим образом (представьте: 4 случайных дерева с 5 листьями в каждом):
library(tidyverse)
# devtools::install_github("hadley/multidplyr")
library(multidplyr)
library(ape)
set.seed(3)
trees <-
map(rep(5, 4), rtree) %>%
do.call(c.phylo, .) %>% # To transform my list of phylo objects in a multiPhylo object
unroot.multiPhylo()
dist.topo(trees)
# tree1 tree2 tree3
# tree2 4
# tree3 4 2
# tree4 4 4 2
Я создал функцию для вычисления расстояний 2 на 2 в data.frame (вдля разделения на кластеры по строкам):
dist.topo2 <- function(multiphylo){
expand.grid(multiphylo, multiphylo) %>%
as.tibble() %>%
mutate(dist = map2(Var1, Var2, dist.topo)) %>%
pull(dist) %>%
matrix(., nrow = sqrt(length(.))) %>%
as.dist()
}
dist.topo2(trees)
# 1 2 3
# 2 4
# 3 4 2
# 4 4 4 2
Как и ожидалось, результат одинаков (независимо от имен).
Затем я добавил функции multidplyr::partition()
и multidplyr::collect()
в моем конвейере:
dist.topo3 <- function(multiphylo){
expand.grid(multiphylo, multiphylo) %>%
as.tibble() %>%
partition() %>%
mutate(dist = purrr::map2(Var1, Var2, ape::dist.topo)) %>%
collect() %>%
pull(dist) %>%
matrix(., nrow = sqrt(length(.))) %>%
as.dist()
}
dist.topo3(trees)
# 1 2 3
# 2 4
# 3 0 4
# 4 2 4 4
# Warning messages:
# 1: In bind_rows_(x, .id) :
# Vectorizing 'multiPhylo' elements may not preserve their attributes
# 2: In bind_rows_(x, .id) :
# Vectorizing 'multiPhylo' elements may not preserve their attributes
# 3: In bind_rows_(x, .id) :
# Vectorizing 'multiPhylo' elements may not preserve their attributes
# 4: In bind_rows_(x, .id) :
# Vectorizing 'multiPhylo' elements may not preserve their attributes
# 5: In bind_rows_(x, .id) :
# Vectorizing 'multiPhylo' elements may not preserve their attributes
# 6: In bind_rows_(x, .id) :
# Vectorizing 'multiPhylo' elements may not preserve their attributes
Как видите, расстояния разные, тогда как операции не изменились.
Как я могу это исправить?Может быть, это невозможно ( См. Здесь )
Спасибо
Примечание: я знаю, что это решение может быть неоптимальным (особенно потому, что оно вычисляет каждое расстояние два раза) но это не главное.