首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在R中重写这段Stata代码?

如何在R中重写这段Stata代码?
EN

Stack Overflow用户
提问于 2011-02-17 10:25:49
回答 4查看 2.3K关注 0票数 9

Stata做得很好的一件事是它构造新变量的方式(参见下面的示例)。如何在R中做到这一点?

代码语言:javascript
复制
foreach i in A B C D {  
    forval n=1990/2000 {  
       local m = 'n'-1  
       # create new columns from existing ones on-the-fly  
       generate pop'i''n' = pop'i''m' * (1 + trend'n')  
   }  
}  
EN

回答 4

Stack Overflow用户

发布于 2011-02-17 16:05:49

不要在R中这样做,它之所以混乱是因为它的代码很难看。使用编程名称构造大量变量是一件坏事。名字就是名字。他们没有结构,所以不要试图强加给他们。好的编程语言有这样的结构--垃圾的编程语言有附加的‘宏’特性,并且以这种通过将字符串粘贴在一起来构造变量名的可怕模式而告终。这是20世纪70年代的一种做法,现在应该已经消失了。不要做一个编程恐龙。

例如,您如何知道您有多少个popXXXX变量?如何知道您是否拥有从pop1990到pop2000的完整序列?如果您想要将变量保存到一个文件中,以便提供给某人,该怎么办?恶,恶,恶。

使用语言提供的数据结构。在本例中,可能是一个列表。

票数 15
EN

Stack Overflow用户

发布于 2011-02-17 23:39:30

Spacedman和Joshua都有非常有效的观点。由于Stata在任何给定时间的内存中只有一个数据集,我建议将变量添加到数据帧(这也是一种列表),而不是全局环境(见下文)。

但老实说,更具R风格的方法是保留因子,而不是变量名。

我制作了一些数据,因为我相信它现在在你的R版本中(至少,我希望如此…)

代码语言:javascript
复制
Data <- data.frame(
    popA1989 = 1:10,
    popB1989 = 10:1,
    popC1989 = 11:20,
    popD1989 = 20:11
)

Trend <- replicate(11,runif(10,-0.1,0.1))

然后,您可以使用stack()函数来获取一个数据帧,其中包含一个因子pop和一个数值变量year

代码语言:javascript
复制
newData <- stack(Data)
newData$pop <- substr(newData$ind,4,4)
newData$year <- as.numeric(substr(newData$ind,5,8))
newData$ind <- NULL

然后填充数据帧就很容易了:

代码语言:javascript
复制
for(i in 1:11){

  tmp <- newData[newData$year==(1988+i),]
  newData <- rbind(newData,
      data.frame( values = tmp$values*Trend[,i],
                  pop = tmp$pop,
                  year = tmp$year+1
      )
  )
}

在此格式中,您将找到大多数R命令(某些年份的选择,单个种群的选择,任意一个或两者的建模效果,...)以后执行起来容易多了。

如果你坚持,你仍然可以用unstack()创建宽格式

代码语言:javascript
复制
unstack(newData,values~paste("pop",pop,year,sep=""))

修改Joshua的回答,将列添加到dataframe中:

代码语言:javascript
复制
for(L in LETTERS[1:4]) {
  for(i in 1990:2000) {
    new <- paste("pop",L,i,sep="")  # create name for new variable
    old <- get(paste("pop",L,i-1,sep=""),Data)  # get old variable
    trend <- Trend[,i-1989]  # get trend variable
    Data <- within(Data,assign(new, old*(1+trend)))
  }
}
票数 9
EN

Stack Overflow用户

发布于 2011-02-17 11:21:03

假设您的全局环境中已经存在popA1989popB1989popC1989popD1989,下面的代码应该可以工作。当然还有更多的“类似R”的方法可以做到这一点,但我想给你一些类似于你的Stata代码的东西。

代码语言:javascript
复制
for(L in LETTERS[1:4]) {
  for(i in 1990:2000) {
    new <- paste("pop",L,i,sep="")  # create name for new variable
    old <- get(paste("pop",L,i-1,sep=""))  # get old variable
    trend <- get(paste("trend",i,sep=""))  # get trend variable
    assign(new, old*(1+trend))
  }
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5024437

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档