【问题标题】:ddply for sum by group in Rddply 在 R 中按组求和
【发布时间】:2023-03-20 17:45:01
【问题描述】:

我有一个示例数据框“数据”,如下所示:

X            Y  Month   Year    income
2281205 228120  3   2011    1000
2281212 228121  9   2010    1100
2281213 228121  12  2010    900
2281214 228121  3   2011    9000
2281222 228122  6   2010    1111
2281223 228122  9   2010    3000
2281224 228122  12  2010    1889
2281225 228122  3   2011    778
2281243 228124  12  2010    1111
2281244 228124  3   2011    200
2281282 228128  9   2010    7889
2281283 228128  12  2010    2900
2281284 228128  3   2011    3400
2281302 228130  9   2010    1200
2281303 228130  12  2010    2000
2281304 228130  3   2011    1900
2281352 228135  9   2010    2300
2281353 228135  12  2010    1333
2281354 228135  3   2011    2340

我想使用 ddply 来计算每个 Y(不是 X)的收入,如果我对每个 Y 有四个观察值(例如 2281223 和 2010 年第 6、9、12 个月和2011 年第 3 个月)。如果我有少于四个观察值(例如 Y = 228130),我想简单地忽略它。为了上述目的,我在R 中使用了以下命令:

require(plyr)
     # the data are in the data csv file
    data<-read.csv("data.csv")
    # convert Y (integers) into factors
    y<-as.factor(y)
    # get the count of each unique Y
    count<-ddply(data,.(Y), summarize, freq=length(Y))
    # get the sum of each unique Y 
    sum<-ddply(data,.(Y),summarize,tot=sum(income))
    # show the sum if number of observations for each Y is less than 4
    colbind<-cbind(count,sum)
    finalsum<-subset(colbind,freq>3)

我的输出如下:

>colbind
       Y freq      Y   tot
1 228120    1 228120  1000
2 228121    3 228121 11000
3 228122    4 228122  6778
4 228124    2 228124  1311
5 228128    3 228128 14189
6 228130    3 228130  5100
7 228135    3 228135  5973
>finalsum
       Y freq    Y.1  tot
3 228122    4 228122 6778

上面的代码可以工作,但是需要很多步骤。所以,我想知道是否有执行上述任务的简单方法(使用 plyr 包)。

【问题讨论】:

  • 您可以使用summarise 一次性创建freqtot 变量,并且可能不需要将Y 转换为因子。

标签: r plyr


【解决方案1】:

正如评论中指出的,您可以在summarize 中执行多项操作。

这会将您的代码减少为一行 ddply() 和一行子集,使用 [ 运算符很容易:

x <- ddply(data, .(Y), summarize, freq=length(Y), tot=sum(income))
x[x$freq > 3, ]

       Y freq  tot
3 228122    4 6778

使用data.table 包也非常简单:

library(data.table)
data.table(data)[, list(freq=length(income), tot=sum(income)), by=Y][freq > 3]
        Y freq  tot
1: 228122    4 6778

实际上,计算向量长度的操作在data.table 中有自己的快捷方式——使用.N 快捷方式:

data.table(data)[, list(freq=.N, tot=sum(income)), by=Y][freq > 3]
        Y freq  tot
1: 228122    4 6778

【讨论】:

  • 谢谢。我将我和你的代码用于我的扩展样本,N(观察次数)约为 35000。执行这两个代码大约需要 200 秒。这在 ddply 函数中正常吗?
  • 是的。 plyr 非常方便,但速度可能很慢,尤其是与 data.table 相比。
【解决方案2】:

我认为dplyr 包比plyr::ddply 更快,更优雅。

testData <- read.table(file = "clipboard",header = TRUE)
require(dplyr)
testData %>%
  group_by(Y) %>%
  summarise(total = sum(income),freq = n()) %>%
  filter(freq > 3)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-12-02
    • 2015-03-23
    • 1970-01-01
    • 2020-08-26
    • 1970-01-01
    • 2021-06-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多