【问题标题】:Calculating summary statistic across subsets of dataset [What is the equivalent of Stata's "bysort" in R?]计算跨数据集子集的汇总统计量 [R 中 Stata 的“按排序”等效于什么?]
【发布时间】:2011-06-23 03:11:34
【问题描述】:

过去几年我一直在 Stata 编程,最近大约 4 个月前切换到 R。

我有以下格式的数据:

       popname sex year age COUNTRY
329447     AUS   f 1921  23     AUS
329448     AUS   f 1921  24     AUS
329449     AUS   f 1921  25     AUS
329450     AUS   f 1921  26     AUS
329451     AUS   f 1921  27     AUS
329452     AUS   f 1921  28     AUS
...
329532     AUS   f 1922  23     AUS
329533     AUS   f 1922  24     AUS
329534     AUS   f 1922  25     AUS
...        ...   .  ..   ..     ...
297729     BLR   f 1987  59     BLR
297730     BLR   f 1987  60     BLR
297731     BLR   f 1987  61     BLR
... 
291941     BLR   m 1973  71     BLR
291942     BLR   m 1973  72     BLR
291993     BLR   m 1974  23     BLR

我想在现有数据集中创建一个名为 Max.Age 的新汇总变量(它计算由 {popname, sex,year 定义的给定子组的最大年龄),如下所示:

   popname sex year age COUNTRY   max.age
329447     AUS   f 1921  23     AUS   72  
329448     AUS   f 1921  24     AUS   72
329449     AUS   f 1921  25     AUS   72
329450     AUS   f 1921  26     AUS   72
329451     AUS   f 1921  27     AUS   72
329452     AUS   f 1921  28     AUS   72
...
329532     AUS   f 1922  23     AUS   75
329533     AUS   f 1922  24     AUS   75
329534     AUS   f 1922  25     AUS   75
...        ...   .  ..   ..     ...
297729     BLR   f 1987  59     BLR   87
297730     BLR   f 1987  60     BLR   87
297731     BLR   f 1987  61     BLR   87
... 
291941     BLR   m 1973  71     BLR   78
291942     BLR   m 1973  72     BLR   78
291993     BLR   m 1974  23     BLR   78

要在 Stata 中执行此操作,可以使用 egen 命令和 by 命令,如下所示:

by State City Day, sort:
egen cnt=seq(), from(23) to(72) block(1);  

我尝试使用 doBy 包在 R 中执行此操作。这是我写的代码:

IDB <- orderBy(~popname+sex+year+age, data=IDB)
v<-lapplyBy(~sex+year, data=IDB, function(d) c(NA,max(d$age)))
IDB$Max.age <- unlist(v)

这不起作用,因为 lapplyBy 返回的聚合数据集长度小于原始数据集 (IDB)。

有人可以为我指出如何在 R 中实现“by | egen”类型的 Stata 代码的正确方向吗?

谢谢

【问题讨论】:

    标签: r stata


    【解决方案1】:

    您会发现使用 R 语言做事的方式不止一种。一种方法是通过ave 函数。

    IDB$max.age <- ave(IDB$age, IDB$popname, IDB$sex, IDB$year, FUN=max)
    

    【讨论】:

      【解决方案2】:

      我建议使用plyr 包中的ddply(尽管有很多方法可以做到这一点)。假设你的数据框被称为dat:

      result <- ddply(dat,.(popname,sex,year),.fun = function(x){
                                               x$max.age <- max(x$age,na.rm=TRUE)
                                               return(x)})
      

      ddply 中的匿名函数为每个片段添加一列,其中包含该片段的最大年龄。

      【讨论】:

      • +1 建议 ddply。这就是我的建议,但你先做了。
      【解决方案3】:

      几年前我尝试阅读 Stata egen 文档时发现它完全不透明,所以我不会给你一个笼统的答案。用于此目的的函数(从应用于组的函数返回相同长度的向量是ave()

      dfrm$max.age <- with( dfrm, ave(age, list(popname, sex,year), FUN=max, na.rm=TRUE) )
      

      您确实收到警告,但操作成功。也许分组变量的叉积会创建稍后被丢弃的空类别。它们也出现在 Joshua 的版本中,删除 na.rm=TRUE 不会更改警告:

      1: In FUN(X[[20L]], ...) : no non-missing arguments to max; returning -Inf
      

      【讨论】:

      • 我认为警告是因为ave 使用interaction 并且组之间的一些交互没有观察到。
      【解决方案4】:

      现在使用 dplyr 很容易做到这一点

      library(dplyr)
      IDB %>% group_by(popname, sex, year) %>% mutate(max.age = max(age))
      

      【讨论】:

        猜你喜欢
        • 2023-03-15
        • 2021-03-29
        • 1970-01-01
        • 2014-05-18
        • 1970-01-01
        • 1970-01-01
        • 2023-01-05
        • 1970-01-01
        • 2020-10-13
        相关资源
        最近更新 更多