我对merge()
函数(在基数R中)与join()
和plyr
的{{1}}函数之间的区别的理解是,dplyr
更快并且在处理“大型”数据集时效率更高。
是否有某种方法可以确定何时使用join()
而不是join()
的阈值,而无需使用启发式方法?
答案 0 :(得分:3)
我敢肯定,当您从一种功能切换到另一种功能时,将很难找到一条“硬而快速”的规则。正如其他人提到的那样,R中提供了一组工具来帮助您评估性能。 object.size
和system.time
是两个这样的函数,分别查看内存使用率和性能时间。一种通用方法是直接在任意扩展的数据集上测量二者。下面是对此的一种尝试。我们将创建一个带有“ id”列和一组随机数值的数据框,以使数据框能够增长并测量其变化。正如您提到的inner_join
,我将在这里使用dplyr
。我们将时间计为“已过”时间。
library(tidyverse)
setseed(424)
#number of rows in a cycle
growth <- c(100,1000,10000,100000,1000000,5000000)
#empty lists
n <- 1
l1 <- c()
l2 <- c()
#test for inner join in dplyr
for(i in growth){
x <- data.frame("id" = 1:i, "value" = rnorm(i,0,1))
y <- data.frame("id" = 1:i, "value" = rnorm(i,0,1))
test <- inner_join(x,y, by = c('id' = 'id'))
l1[[n]] <- object.size(test)
print(system.time(test <- inner_join(x,y, by = c('id' = 'id')))[3])
l2[[n]] <- system.time(test <- inner_join(x,y, by = c('id' = 'id')))[3]
n <- n+1
}
#empty lists
n <- 1
l3 <- c()
l4 <- c()
#test for merge
for(i in growth){
x <- data.frame("id" = 1:i, "value" = rnorm(i,0,1))
y <- data.frame("id" = 1:i, "value" = rnorm(i,0,1))
test <- merge(x,y, by = c('id'))
l3[[n]] <- object.size(test)
# print(object.size(test))
print(system.time(test <- merge(x,y, by = c('id')))[3])
l4[[n]] <- system.time(test <- merge(x,y, by = c('id')))[3]
n <- n+1
}
#ploting output (some coercing may happen, so be it)
plot <- bind_rows(data.frame("size_bytes" = l3, "time_sec" = l4, "id" = "merge"),
data.frame("size_bytes" = l1, "time_sec" = l2, "id" = "inner_join"))
plot$size_MB <- plot$size_bytes/1000000
ggplot(plot, aes(x = size_MB, y =time_sec, color = id)) + geom_line()
merge
的性能似乎较差,但实际上大约在20MB左右。这是最后的决定吗?不会。但是这样的测试可以使您了解如何选择功能。