Перевод Stata в R: свернуть

Просто наткнулся на .do файл, который мне нужно перевести в R потому что у меня нет лицензии Stata; моя Stata ржавая, поэтому кто-то может подтвердить, что код делает то, что я думаю?

Для воспроизводимости я собираюсь перевести его в набор данных, который я нашел в Интернете, в частности набор данных по производству молока (p004), который является частью учебника Чаттерджи, Хади и Прайса.

Вот код Stata:

collapse (min) min_protein = protein /// 
         (mean) avg_protein = protein /// 
         (median) median_protein = protein /// 
         (sd) sd_protein = protein /// 
         if protein > 2.8, by(lactatio)

Вот что я думаю это делает в data.table синтаксис:

library(data.table)
library(foreign)
DT = read.dta("p004.dta")
setDT(DT)

DT[protein > 2.8,
   .(min_protein = min(protein),
     avg_protein = mean(protein),
     median_protein = median(protein),
     sd_protein = sd(protein)),
   keyby = lactatio]

#    lactatio min_protein avg_protein median_protein sd_protein
# 1:        1         2.9    3.162632           3.10  0.2180803
# 2:        2         2.9    3.304688           3.25  0.2858736
# 3:        3         2.9    3.371429           3.35  0.4547672
# 4:        4         2.9    3.231250           3.20  0.3419917
# 5:        5         2.9    3.855556           3.20  1.9086061
# 6:        6         3.0    3.200000           3.10  0.2645751
# 7:        7         3.3    3.650000           3.65  0.4949748
# 8:        8         3.2    3.300000           3.30  0.1414214

Это верно?

Это было бы легко подтвердить, если бы я использовал Stata за последние 18 месяцев или если у меня была установлена ​​копия - в надежде, что я смогу подслушать кого-то, для кого любое из них верно. Благодарю.

2 ответа

Решение

Ваша интуиция верна. collapse это Stata эквивалент R aggregate функция, которая создает новый набор данных из входного набора данных, применяя функцию агрегирования (или несколько функций агрегации, по одной на переменную) к каждой переменной в наборе данных.

Вот вывод для этой команды Stata в примере набора данных:

. list

     +------------------------------------------------------+
     | lactatio   min_pr~n   avg_pr~n   median~n   sd_pro~n |
     |------------------------------------------------------|
  1. |        1        2.9   3.162632        3.1   .2180803 |
  2. |        2        2.9   3.304688       3.25   .2858736 |
  3. |        3        2.9   3.371429       3.35   .4547672 |
  4. |        4        2.9    3.23125        3.2   .3419917 |
  5. |        5        2.9   3.855556        3.2   1.908606 |
     |------------------------------------------------------|
  6. |        6          3        3.2        3.1   .2645752 |
  7. |        7        3.3       3.65       3.65   .4949748 |
  8. |        8        3.2        3.3        3.3   .1414214 |
     +------------------------------------------------------+

Вот вывод Stata для ваших образцов данных, который идентичен data.table выход:

collapse (min) min_protein = protein /// 
         (mean) avg_protein = protein /// 
         (median) median_protein = protein /// 
         (sd) sd_protein = protein /// 
         if protein > 2.8, by(lactatio)

   lactatio min_protein avg_protein median_protein  sd_protein
     1  2.9 3.162632    3.1 0.2180803
     2  2.9 3.304688    3.25 0.2858736
     3  2.9 3.371429    3.35 0.4547672
     4  2.9 3.23125     3.2 0.3419917
     5  2.9 3.855556    3.2 1.908606
     6  3   3.2         3.1 0.2645752
     7  3.3 3.65        3.65 0.4949748
     8  3.2 3.3         3.3 0.1414214

и вот data.table вывод (просто чтобы убедиться, что я использую правильные данные)

    library(foreign) #reading Stata data
    data<-read.dta("p004.dta")
    setkey(setDT(data),lactatio)
    setDT(data)[protein>2.8,
                   .(min_protein=min(protein),
                     avg_protein=mean(protein),
                     median_protein=median(protein),
                     sd_protein=sd(protein)),
                   by=lactatio]

   lactatio min_protein avg_protein median_protein sd_protein
1:        1         2.9    3.162632           3.10  0.2180803
2:        2         2.9    3.304688           3.25  0.2858736
3:        3         2.9    3.371429           3.35  0.4547672
4:        4         2.9    3.231250           3.20  0.3419917
5:        5         2.9    3.855556           3.20  1.9086061
6:        6         3.0    3.200000           3.10  0.2645751
7:        7         3.3    3.650000           3.65  0.4949748
8:        8         3.2    3.300000           3.30  0.1414214
> 
stata.collapse<-function(data,vars,newnames,stat,by) {
m=match(by,names(data))
data1=data[m]
x=length(by)
l=length(stat)

for (i in 1:l){
   nn=aggregate(data[vars[i]],by=data1,stat[i],na.rm=TRUE) 
   d=names(nn)
   d[ncol(data1)+1]<-newnames[i]
    names(nn)<-d
     xx1=nn[1:x]
     xx=nn[-(1:x)]
         if (i>1) {
         x2=cbind(x2,xx)
         }else {
        x2=nn
}
}

return(x2)
}

Для запуска вызовите эту функцию, как это

  h=stata.collapse(roster,c("idcode1","age","age") , 
    c("hhsize","meanage","maxage"),c("max","mean","max"),c("psu","hhno"))
Другие вопросы по тегам