use*_*119 10 r dplyr data.table
我希望根据列总结我的数据框中的一些变量.但是我的数据框相当大(> 30,000,000行),并且使用dplyr中的汇总函数需要很长时间才能运行.R中是否有更快的方法来加速汇总过程?
我有一个格式的数据框df:
proid X1 X2 X3 X4
1 1 zz a e a
2 2 ff g z b
3 1 cd s f d
4 3 ab t e e
5 2 ta b h k
....
Run Code Online (Sandbox Code Playgroud)
我希望在它们具有相同的prodid值时连接变量X1到X4.连接的字符串用逗号分隔.所以上面的表应该给我新表:
proid X1 X2 X3 X4
1 1 zz,cd a,s e,f a,d
2 2 ff,ta g,b z,h b,k
3 3 ab t e e
....
Run Code Online (Sandbox Code Playgroud)
我使用了以下dplyr代码:
concat <- function(x){
x <- na.omit(x)
if(length(x)==0){
return(as.character(NA))
}else{
return(paste(x,collapse=","))
}
}
dg<-group_by(df,proid)
df<-summarise(dg,proid,concat(X1),concat(X2),concat(X3),concat(X4))
Run Code Online (Sandbox Code Playgroud)
tal*_*lat 11
编辑注释:删除了我的答案的原始部分,没有解决NA处理并添加了基准.
concat2 <- function(x) if(all(is.na(x))) NA_character_ else paste(na.omit(x), collapse = ",")
Run Code Online (Sandbox Code Playgroud)
使用data.table:
setDT(df)[, lapply(.SD, concat2), by = proid, .SDcols = -c("X4")]
# proid X1 X2 X3
#1: 1 zz,cd a,s e,f
#2: 2 ff,ta g,b z,h
#3: 3 NA t e
Run Code Online (Sandbox Code Playgroud)
使用dplyr:
df %>% group_by(proid) %>% summarise_each(funs(concat2), -X4)
Run Code Online (Sandbox Code Playgroud)
基准测试,比实际使用情况更小的数据而且没有完全代表性,所以只是想得到一个concat2比较concat等等的印象.
library(microbenchmark)
library(dplyr)
library(data.table)
N <- 1e6
x <- c(letters, LETTERS)
df <- data.frame(
proid = sample(1e4, N, TRUE),
X1 = sample(sample(c(x, NA), N, TRUE)),
X2 = sample(sample(c(x, NA), N, TRUE)),
X3 = sample(sample(c(x, NA), N, TRUE)),
X4 = sample(sample(c(x, NA), N, TRUE))
)
dt <- as.data.table(df)
concat <- function(x){
x <- na.omit(x)
if(length(x)==0){
return(as.character(NA))
}else{
return(paste(x,collapse=","))
}
}
concat2 <- function(x) if(all(is.na(x))) NA_character_ else paste(na.omit(x), collapse = ",")
concat.dplyr <- function(){
df %>% group_by(proid) %>% summarise_each(funs(concat), -X4)
}
concat2.dplyr <- function(){
df %>% group_by(proid) %>% summarise_each(funs(concat2), -X4)
}
concat.data.table <- function(){
dt[, lapply(.SD, concat), by = proid, .SDcols = -c("X4")]
}
concat2.data.table <- function(){
dt[, lapply(.SD, concat2), by = proid, .SDcols = -c("X4")]
}
microbenchmark(concat.dplyr(),
concat2.dplyr(),
concat.data.table(),
concat2.data.table(),
unit = "relative",
times = 10L)
Unit: relative
expr min lq median uq max neval
concat.dplyr() 1.058839 1.058342 1.083728 1.105907 1.080883 10
concat2.dplyr() 1.057991 1.065566 1.109099 1.145657 1.079201 10
concat.data.table() 1.024101 1.018443 1.093604 1.085254 1.066560 10
concat2.data.table() 1.000000 1.000000 1.000000 1.000000 1.000000 10
Run Code Online (Sandbox Code Playgroud)
调查结果:data.table在样本数据上的执行速度比dplyr快concat2一点,速度比concat.但是,此样本数据集的差异仍然很小.