按因子多列的多个统计信息

时间:2016-08-10 02:07:23

标签: r dplyr plyr

假设我想计算以下数据帧的“dat_1”到“dat_3”列的平均值,标准差和 n (非NA值的数量),按因素“fac_1”和“fac_2”,可以从结果中访问每个统计(或函数)的单独数据帧

set.seed(1)
df <- data.frame("fac_1" = c(rep("a", 5), rep("b", 4)),
             "fac_2" = c("x", "x", "y","y", "y", "y", "x", "x", "x"),
             "dat_1" = c(floor(runif(3, 0, 10)), NA, floor(runif(5, 0, 10))),
             "dat_2" = floor(runif(9, 10, 20)),
             "dat_3" = floor(runif(9, 20, 30)))

这可以使用plyr一次实现一个功能,就像这样

ddply(.data = df, .variables = .(df$fac_1, df$fac_2), .fun = function(x) { colMeans(x[, 3:5], na.rm = T) } ) # mean
ddply(.data = df, .variables = .(df$fac_1, df$fac_2), .fun = function(x) { psych::SD(x[, 3:5], na.rm = T) } ) # standrd deviation -- note uses SD from the 'psych' package
ddply(.data = df, .variables = .(df$fac_1, df$fac_2), .fun = function(x) { colSums(!is.na(x[, 3:5])) } ) # number of non-NA values

但是当使用多个函数时,这会变得很麻烦,特别是当必须更改感兴趣的因子和列时。我想知道是否有另一种选择(也许是一个单行)。

汇总作品

aggregate( x = df[, c(3:5)], by = df[, c(1,2)], FUN = function(x) c(n = length( !is.na(x) ), mean = mean(x, na.rm = T), sd = sd(x, na.rm = T) ) )

但是“分解”结果(分成每个统计数据的单独数据框)变得很尴尬。

最近我遇到了dplyr。以下似乎有效

df %>% group_by(fac_1, fac_2) %>% summarise_each(funs(n = length( !is.na(.) ), mean(., na.rm = TRUE), sd(., na.rm = TRUE) )) # using dplyr

但是我希望能够将因子粘贴到group_by()中,而我却找不到这样做的方法。

任何帮助或想法?感谢

1 个答案:

答案 0 :(得分:1)

将向量或列表传递给dplyr函数可能很棘手(参见this vignette.)简而言之,它涉及添加额外的下划线,使用函数的标准求值版本,然后将向量或列表传递给.dots论证。

factorsToSummarise <-
  c('fac_1', 'fac_2')

   # extra underscore
        # |
df %>%  # v
  group_by_(.dots = factorsToSummarise) %>% 
  summarise_each(funs(n = length( !is.na(.) ), 
                      mean(., na.rm = TRUE), 
                      sd(., na.rm = TRUE) 
  )) # using dplyr