How to rewrite this Stata code in R?

后端 未结 4 654
挽巷
挽巷 2021-01-02 07:34

One of the things Stata does well is the way it constructs new variables (see example below). How to do this in R?

foreach i in A B C D {  
    forval n=1990         


        
4条回答
  •  梦谈多话
    2021-01-02 08:08

    Both Spacedman and Joshua have very valid points. As Stata has only one dataset in memory at any given time, I'd suggest to add the variables to a dataframe (which is also a kind of list) instead of to the global environment (see below).

    But honestly, the more R-ish way to do so, is to keep your factors factors instead of variable names.

    I make some data as I believe it is in your R version now (at least, I hope so...)

    Data <- data.frame(
        popA1989 = 1:10,
        popB1989 = 10:1,
        popC1989 = 11:20,
        popD1989 = 20:11
    )
    
    Trend <- replicate(11,runif(10,-0.1,0.1))
    

    You can then use the stack() function to obtain a dataframe where you have a factor pop and a numeric variable year

    newData <- stack(Data)
    newData$pop <- substr(newData$ind,4,4)
    newData$year <- as.numeric(substr(newData$ind,5,8))
    newData$ind <- NULL
    

    Filling up the dataframe is then quite easy :

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

    In this format, you'll find most R commands (selections of some years, of a single population, modelling effects of either or both, ...) a whole lot easier to perform later on.

    And if you insist, you can still create a wide format with unstack()

    unstack(newData,values~paste("pop",pop,year,sep=""))
    

    Adaptation of Joshua's answer to add the columns to the dataframe :

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

提交回复
热议问题