使用ddply + summarize对大量列重复应用相同的统计函数

23

好的,这是相继提出的第二个R问题。

我的数据:

           Timestamp    St_01  St_02 ...
1 2008-02-08 00:00:00  26.020 25.840 ...
2 2008-02-08 00:10:00  25.985 25.790 ...
3 2008-02-08 00:20:00  25.930 25.765 ...
4 2008-02-08 00:30:00  25.925 25.730 ...
5 2008-02-08 00:40:00  25.975 25.695 ...
...

通常情况下,我会结合使用ddplysummarize来计算集合(例如,整年每小时的均值)。

在上述情况下,我会创建一个类别,比如小时(例如,strptime(data$Timestamp,"%H") -> data$hour),然后在ddply中使用该类别,如ddply(data,"hour", summarize, St_01=mean(St_01), St_02=mean(St_02)...) ,以对每列按类别进行平均。

但这里有个问题。我有超过40列需要处理,而且我不想将它们作为参数一个个地输入summarize函数中。以前我会在shell中编写循环来生成此代码,但程序员不是这样解决问题的,对吧?

那么,请问是否有更好的方法以减少击键量的方式实现相同的结果呢?


2
或者将 St 变量转换为长格式,然后使用您喜欢的聚合函数 byaggregateddplyc(hour,index) 组合,其中 index 是在重塑过程中创建的变量。 - Ari B. Friedman
易点数:) - user557846
lol谢谢!哈哈哈。对人性的信心恢复了。 - Reuben L.
2个回答

38

你可以使用numcolwise()对所有数值列运行汇总。

以下是使用iris的示例:

ddply(iris, .(Species), numcolwise(mean))
     Species Sepal.Length Sepal.Width Petal.Length Petal.Width
1     setosa        5.006       3.428        1.462       0.246
2 versicolor        5.936       2.770        4.260       1.326
3  virginica        6.588       2.974        5.552       2.026
类似地,使用catcolwise()可以对所有分类列进行总结。
有关更多帮助和示例,请参见?numcolwise

编辑

另一种方法是使用reshape2(由@gsk3提出)。 在这个示例中,这需要更多击键,但可以给您带来巨大的灵活性:

library(reshape2)

miris <- melt(iris, id.vars="Species")
x <- ddply(miris, .(Species, variable), summarize, mean=mean(value))

dcast(x, Species~variable, value.var="mean")
     Species Sepal.Length Sepal.Width Petal.Length Petal.Width
1     setosa        5.006       3.428        1.462       0.246
2 versicolor        5.936       2.770        4.260       1.326
3  virginica        6.588       2.974        5.552       2.026

一个问题,它如何与总结功能一起使用?因为我也需要在每列中进行分类汇总。 - Reuben L.
1
我不确定你的意思。通常使用colwise或其相关函数,就不需要使用summarize。你能否详细说明你的问题? - Andrie
@R-L 这是二选一,两种不同的方法。两者都有其优点。如果您要对每列进行大量的统计计算并想要查看中间结果,则“melt”方法非常简洁。 - smci

7

您甚至可以简化Andrie提出的第二种方法,完全省略ddply调用。只需在dcast调用中指定mean作为聚合函数即可:

library(reshape2)
miris <- melt(iris, id.vars="Species")
dcast(miris, Species ~ variable, mean)

     Species Sepal.Length Sepal.Width Petal.Length Petal.Width
1     setosa        5.006       3.428        1.462       0.246
2 versicolor        5.936       2.770        4.260       1.326
3  virginica        6.588       2.974        5.552       2.026

使用data.table包也可以非常快速地计算出相同的结果。在j表达式中的.SD变量是一个特殊的data.table变量,它包含了每个组的数据子集,但排除了在by中使用的所有列。

library(data.table)
dt_iris <- as.data.table(iris)
dt_iris[, lapply(.SD, mean), by = Species]

     Species Sepal.Length Sepal.Width Petal.Length Petal.Width
1:     setosa        5.006       3.428        1.462       0.246
2: versicolor        5.936       2.770        4.260       1.326
3:  virginica        6.588       2.974        5.552       2.026

另一个选择是Hadley的新版本0.2的dplyr软件包。

library(dplyr)
group_by(iris, Species) %>% summarise_each(funs(mean))

Source: local data frame [3 x 5]

     Species Sepal.Length Sepal.Width Petal.Length Petal.Width
1     setosa        5.006       3.428        1.462       0.246
2 versicolor        5.936       2.770        4.260       1.326
3  virginica        6.588       2.974        5.552       2.026

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接