聚合列列表的大数据集并使用不同的 FUN

Aggregate big dataset for a list of columns and using different FUN

我有一个大数据集,我需要通过一个因素 (CODE_PLOT) 来汇总大部分列。这是我需要聚合的列的列表:

> names(soil)[4:30]
 [1] "PH"            "CONDUCTIVITY"  "K"             "CA"            "MG"            "N_NO3"        
 [7] "S_SO4"         "ALKALINITY"    "AL"            "DOC"           "WATER_CONTENT" "Na"           
[13] "AL_LABILE"     "FE"            "MN"            "P"             "N_NH4"         "CL"           
[19] "CR"            "NI"            "ZN"            "CU"            "PB"            "CD"           
[25] "SI"            "SAMPLE_VOL"    "N_TOTAL"      

对于那些列,我需要均值、标准差和长度值。 由于数据集很大,性能也很重要。 我试过聚合,但没有用。我对其他可以更快完成的软件包持开放态度。我的尝试:

soil_variables <- names(soil)[4:30]
soil_by <- "CODE_PLOT"
soilM <- aggregate(soil[soil_variables], by=soil[soil_by],data=soil,
                   FUN=function(x) c(mn =mean(x),n=length(x)),na.rm=T)

所需的输出是一个数据框,每个变量有 3 列:平均值、sd 和 N(27x3 列 + 1“by”列)

您可以使用 dplyr 的 summarise_each 函数结合 group_by:

library(dplyr)
soil %>%
  group_by(CODE_PLOT) %>%
  summarise_each(funs(mean = mean(., na.rm = TRUE), 
                      sd = sd(., na.rm = TRUE), 
                      N = n()), 4:30)

这将汇总数据的 4:30 列。

如果您想提供要汇总的列名向量(如示例中的 soil_variables),您可以这样做:

soil_variables <- names(soil)[4:30]

soil %>%
  group_by(CODE_PLOT) %>%
  summarise_each_(funs(mean = mean(., na.rm = TRUE),      # note "summarise_each_"
                      sd = sd(., na.rm = TRUE), 
                      N = n()), soil_variables)

这是一个 "iris" 数据集的示例,按 "Species" 组汇总两列:

data(iris)
iris %>% 
  group_by(Species) %>% 
  summarise_each(
    funs(
      mean = mean(., na.rm = TRUE),
      sd = sd(., na.rm = TRUE),
      N = n()
      ), 1:2)

#Source: local data frame [3 x 7]
#
#     Species Sepal.Length_mean Sepal.Width_mean Sepal.Length_sd Sepal.Width_sd Sepal.Length_N Sepal.Width_N
#1     setosa             5.006            3.428       0.3524897      0.3790644             50            50
#2 versicolor             5.936            2.770       0.5161711      0.3137983             50            50
#3  virginica             6.588            2.974       0.6358796      0.3224966             50            50
library(data.table)
dt = data.table(a = 1:2, b = 1:10, c = 2:11)

dt[, as.list(unlist(lapply(.SD, function(x) c(mn = mean(x), sd = sd(x), n = .N))))
   , by = a]
#   a b.mn     b.sd b.n c.mn     c.sd c.n
#1: 1    5 3.162278   5    6 3.162278   5
#2: 2    6 3.162278   5    7 3.162278   5

您可以添加 .SDcols 以指定要在哪些列上执行此操作。