Вычисление сводной статистики по подмножествам набора данных [Что эквивалентно «сортировке» Stata в R?] - PullRequest
4 голосов
/ 23 июня 2011

Я программировал в Stata последние несколько лет, а недавно перешел на R около 4 месяцев назад.

У меня есть данные в следующем формате:

       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);  

Я попытался сделать это в R, используя пакет doBy. Вот код, который я написал:

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).

Может ли кто-нибудь указать мне правильное направление, как по существу реализовать код Stata типа "by | egen" в R?

Спасибо

Ответы [ 4 ]

5 голосов
/ 23 июня 2011

Одна вещь, которую вы найдете с R, это то, что не существует только одного способа сделать что-то.Один из способов - через функцию ave.

IDB$max.age <- ave(IDB$age, IDB$popname, IDB$sex, IDB$year, FUN=max)
4 голосов
/ 23 июня 2011

Я бы порекомендовал использовать ddply из пакета plyr (хотя есть много способов сделать что-то подобное). Предполагая, что ваш фрейм данных называется dat:

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

Анонимная функция в ddply добавляет столбец к каждому элементу с максимальным возрастом для этого элемента.

3 голосов
/ 23 июня 2011

Я обнаружил, что документация Stata egen совершенно непрозрачна, когда я пытался прочитать ее пару лет назад, поэтому я не буду давать вам общий ответ. Функция, используемая для этой цели (возвращающий вектор одинаковой длины из функции, примененной к группам, равен ave():

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

Вы получаете предупреждения, но операция завершается успешно. Возможно, перекрестный продукт группирующих переменных создает пустые категории, которые впоследствии отбрасываются. Они также происходят с версией Джошуа, и удаление na.rm = TRUE не меняет предупреждения:

1: In FUN(X[[20L]], ...) : no non-missing arguments to max; returning -Inf
0 голосов
/ 04 июня 2015

Это легко сделать, используя dplyr

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