【问题标题】:Translating Stata to R: collapse将Stata翻译成R:崩溃
【发布时间】:2015-09-08 09:06:22
【问题描述】:

刚刚遇到一个.do 文件,我需要将其翻译成R,因为我没有Stata 许可证;我的 Stata 生锈了,所以有人可以确认代码正在做我认为的事情吗?

为了可重复性,我将把它翻译成我在网上找到的数据集,特别是 Milk Production dataset (p004),它是 Chatterjee、Hadi 和 Price 教科书的一部分。

这是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

对吗?

这很容易确认我是否在过去 18 个月中使用过 Stata,或者我是否安装了副本——希望我能听听那些对其中任何一个都属实的人的看法。谢谢。

【问题讨论】:

  • 请注意,您可以随时在线访问 Stata 的帮助文件(例如collapse),以帮助澄清代码。
  • 是的,我读到了,这就是为什么我认为我提供的R 代码是正确的。只是希望得到对这两种语言相当熟悉的人的确认。
  • 100% 正确。但是,如果您提供示例数据,我可以重现输出。
  • 您的翻译很好,但重复了很多 varname。你可以用一个命名的函数列表来做一些事情,比如DT <- data.table(id=1:3)[,.(x=sample(10,5)),by=id]; DT[,lapply(list(minx = min, meanx = mean, medx = median, sdx = sd),function(f)f(x)),by=id]
  • @MichaelChirico 仅供参考,有一个 statar 包可能有助于将 stata 转换为 R

标签: r data.table stata code-translation


【解决方案1】:

这是您的样本数据的 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
> 

【讨论】:

    【解决方案2】:

    你的直觉是正确的。 collapse 是 R 的 aggregate 函数的 Stata 等效函数,它通过将聚合函数(或多个聚合函数,每个变量一个)应用到数据集中的每个变量,从输入数据集生成新数据集。

    这是示例数据集上该 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 的崩溃让您可以一次创建多个聚合,而 R 的聚合只提供一个(据我所知)。似乎 OP 的 data.table 操作(或 dplyr 中的类似操作)是一个更好的模拟。
    • @Frank 是也不是。 Data.table 做了很多想法,每个想法都被不同的 Stata 命令覆盖(例如,dropkeepcollapsemergeexpandreshape 等)。最直接的类似物是aggregate,尽管aggregatecollapse 的工作方式略有不同。 FUN 参数 aggregate 意味着您可以指定特定于类的聚合函数,因此使用 aggregate 生成相同的功能是可行的(如果冗长的话)。
    • 嗯,好吧,我不同意,因为我从未见过aggregate以这种方式使用;和by(以及六个其他功能)可能会在足够的扭曲下做同样的事情。我指的不是 data.table 的广泛用途,而是上面的语法,它采用 .(newx = f(x), newy = g(y), newz = h(z)), by=id 的形式,它与 R 中的 Stata 语法一样接近。
    【解决方案3】:
    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"))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-08
      • 2022-11-30
      • 2020-04-29
      • 2020-08-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-17
      相关资源
      最近更新 更多