计算数据集子集的汇总统计量[Stata"#34; bysort"在R?]

时间:2011-06-23 03:11:34

标签: r stata

过去几年我一直在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代码吗?

谢谢

4 个答案:

答案 0 :(得分:5)

你会发现R有一件事就是不只有一种方法可以做。一种方法是通过ave函数。

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

答案 1 :(得分:4)

我建议使用ddply包中的plyr(虽然有很多方法可以做这样的事情)。假设您的数据框名为dat

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

ddply中的匿名函数会为每件作品添加一列,其中包含该作品的最大年龄。

答案 2 :(得分: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

答案 3 :(得分:0)

现在可以使用dplyr

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