在R中有效地设置非常大的数据帧

pet*_*ule 0 r large-data bigdata dataframe

所以我有一个16列和大约1700万行的数据框.

我首先想ddply在数据框上做一些,然后查看不同列之间的相关性.实现这一目标的最佳和最有效的方法是什么?我目前的方法花了太长时间:

该数据帧all_df和列名A,B,C,..., ,,NOP

avB <- ddply(all_df, c(“A”), summarise, NB_av=mean(B), NB_sd=sd(B))
avC <- ddply(all_df, c(“A”), summarise, NC_av=mean(C), NC_sd=sd(C))
avD <- ddply(all_df, c(“A”), summarise, ND_av=mean(D), ND_sd=sd(D))
avE <- ddply(all_df, c(“A”), summarise, NE_av=mean(E), NE_sd=sd(E))
avF <- ddply(all_df, c(“A”), summarise, NF_av=mean(F), NF_sd=sd(F))
avG <- ddply(all_df, c(“A”), summarise, NG_av=mean(G), NG_sd=sd(G))

summary_df <- avB
summary_df <- merge(summary_df, avC, by=c(“A”))
summary_df <- merge(summary_df, avD, by=c(“A”))
summary_df <- merge(summary_df, avE, by=c(“A”))
summary_df <- merge(summary_df, avF, by=c(“A”))
summary_df <- merge(summary_df, avG, by=c(“A”))

#quick look at the correlation
plot((summary_df[,c(2,4,6,8,10,12)]), gap=0) 
Run Code Online (Sandbox Code Playgroud)

所以,实际上,我正在解决在MySQL中做很多这些,平均值,标准偏差等,然后在R中做最后的相关关系分析.但是,我没有发现它非常优雅.

为什么我使用数据框而不是数据表?因为我正在读取R中的MySQL表,并且语法dbGetQuery(con,"select * from mysql_table")返回一个数据帧.

akr*_*run 5

你可以试试

library(dplyr)
 all_df %>% 
       group_by(A) %>% 
       summarise_each(funs(mean, sd), B:G)
Run Code Online (Sandbox Code Playgroud)

或者另一个选择是 data.table

library(data.table)
setDT(all_df)[, lapply(.SD, function(x) c(mean(x), sd(x))), by = A,
              .SDcols=LETTERS[2:6]][,var:= c('mean', 'sd')][]
Run Code Online (Sandbox Code Playgroud)

注意:第一种形式的结果是宽格式,而第二种形式的结果是'mean','sd'作为替代行.

基准

 all_df1 <- all_df[rep(1:nrow(all_df), 1e5),]
 system.time(all_df1%>% group_by(A) %>% summarise_each(funs(mean, sd), B:G))
 #  user  system elapsed 
 # 0.189   0.000   0.189 

 DT1 <- as.data.table(all_df1)
 system.time(DT1[,lapply(.SD, function(x) c(mean(x), sd(x))),
              A, .SDcols=LETTERS[2:6]][,var:= c('mean', 'sd')][])
 #  user  system elapsed 
 #0.232   0.002   0.235 
Run Code Online (Sandbox Code Playgroud)

数据

set.seed(25)
m1 <- matrix(sample(1:20, 15*20, replace=TRUE), ncol=15)
set.seed(353)
all_df <- data.frame(sample(letters[1:3], 20, replace=TRUE), m1)
colnames(d1) <- LETTERS[1:ncol(d1)]    
Run Code Online (Sandbox Code Playgroud)