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