4

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

4 回答 4

5

你会发现 R 的一件事是,做事的方法不止一种。一种方法是通过ave函数。

IDB$max.age <- ave(IDB$age, IDB$popname, IDB$sex, IDB$year, FUN=max)
于 2011-06-23T03:45:47.353 回答
4

我建议ddplyplyr包中使用(尽管有很多方法可以做这样的事情)。假设您的数据框被称为dat

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

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

于 2011-06-23T03:46:59.947 回答
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
于 2011-06-23T03:45:11.770 回答
0

现在使用这很容易做到dplyr

library(dplyr)
IDB %>% group_by(popname, sex, year) %>% mutate(max.age = max(age))
于 2015-06-03T23:51:57.583 回答