【问题标题】:Dynamically create a variable within a loop and add to dataframe在循环中动态创建变量并添加到数据框
【发布时间】:2021-12-18 21:54:23
【问题描述】:

在 STATA 中,在循环中动态创建变量很容易,因为引号 `' 标识了迭代器。这个例子是创建一个二进制变量 Y200X,如果年份小于 200X,则取值为 1:

set obs 10
gen Year = 2005
replace Year = 2010 if _n > 4

forvalues y = 2005(1)2020 {
    gen byte Y`y' = 0
    replace Y`y' = 1 if Year < `y' 
    }

在 R 中,迭代器不能直接用于创建变量名。我发现最好的方法是首先在循环中创建变量,然后将它们组装回循环外的数据框中:

Year <- c(2005,2010,1996,1994,2001,2006,2019,2021, 2018,1987)
ls.output <- as.data.frame(Year)

for(y in 2005:2020) {
  assign(paste0("Y",y), ifelse(ls.output$Year < y, 1, 0))
}
ls.output<- cbind(ls.output, Y2005,Y2006,Y2007,Y2009, Y2010)

有没有更好的方法可以直接在循环中执行此操作?

【问题讨论】:

    标签: r loops


    【解决方案1】:

    列名可以pasted 一起。跳过创建单独变量然后将它们作为列添加到数据框中的步骤,而是直接添加它们:

    for(y in 2005:2020) {
      ls.output[, paste0("Y", y)] <- ifelse(ls.output$Year < y, 1, 0)
    }
    
    ls.output
    #    Year Y2005 Y2006 Y2007 Y2008 Y2009 Y2010 Y2011 Y2012 Y2013 Y2014 Y2015 Y2016 Y2017 Y2018 Y2019 Y2020
    # 1  2005     0     1     1     1     1     1     1     1     1     1     1     1     1     1     1     1
    # 2  2010     0     0     0     0     0     0     1     1     1     1     1     1     1     1     1     1
    # 3  1996     1     1     1     1     1     1     1     1     1     1     1     1     1     1     1     1
    # 4  1994     1     1     1     1     1     1     1     1     1     1     1     1     1     1     1     1
    # 5  2001     1     1     1     1     1     1     1     1     1     1     1     1     1     1     1     1
    # 6  2006     0     0     1     1     1     1     1     1     1     1     1     1     1     1     1     1
    # 7  2019     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     1
    # 8  2021     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0
    # 9  2018     0     0     0     0     0     0     0     0     0     0     0     0     0     0     1     1
    # 10 1987     1     1     1     1     1     1     1     1     1     1     1     1     1     1     1     1
    

    【讨论】:

    • 谢谢!祝您有美好的一天!
    【解决方案2】:

    使用outer,其中Year 与问题中的定义相同。

    data.frame(Year, +outer(Year, setNames(2005:2010, paste0("Y", 2005:2010)), `<`))
    

    给予:

       Year Y2005 Y2006 Y2007 Y2008 Y2009 Y2010
    1  2005     0     1     1     1     1     1
    2  2010     0     0     0     0     0     0
    3  1996     1     1     1     1     1     1
    4  1994     1     1     1     1     1     1
    5  2001     1     1     1     1     1     1
    6  2006     0     0     1     1     1     1
    7  2019     0     0     0     0     0     0
    8  2021     0     0     0     0     0     0
    9  2018     0     0     0     0     0     0
    10 1987     1     1     1     1     1     1
    

    【讨论】:

    • 谢谢你也非常巧妙的解决方案!
    猜你喜欢
    • 1970-01-01
    • 2021-03-25
    • 1970-01-01
    • 2014-04-13
    • 1970-01-01
    • 2019-04-09
    • 2015-03-06
    • 2019-06-14
    • 1970-01-01
    相关资源
    最近更新 更多