【问题标题】:How to create a new column that's name contains a variable name (in a loop)?如何创建一个名称包含变量名称的新列(在循环中)?
【发布时间】:2016-05-16 18:19:52
【问题描述】:

我有一个包含行索引号的向量,我想根据这些数字创建一个新的虚拟变量,即向量中存在的行在新变量中的值为 1。我在循环中尝试这个,我需要新的变量名来包含循环变量的值。问题似乎是我无法为该变量分配任何值,除非它存在,但我也无法创建它。

下面是一个带有一些伪数据和命令的示例。

set.seed(100)
df <- data.frame(id = 1:20, 
                 year = sample(2011:2013, 20, replace = TRUE), 
                 dum = sample(0:1, 20, rep = TRUE), 
                 var = sample(10:99, 20))
for (x in 2011:2013) {
# Below I take a subset of data to test models for different years.
  assign(paste0("subset.", x), df[df$year == x, ])
  # Here I would test a model.
# Below I imitate matching of propensity scores and create an object that contains 
# row indexes of control group.
  set.seed(x)
  assign(paste0("matching.", x), list(data = df, index.control = sample(1:20, 4)))
# Below I attempt to take the row indexes ofcontrol goup from the created 'matching' object and create 
# a new dummy variable that determines the control group. None of the commands work.
  assign(get(paste0("subset.", x))[get(paste0("matching.", x))$index.control, paste0("control.", x)], 1)
  get(paste0("subset.", x))[get(paste0("matching.", x))$index.control, paste0("control.", x)] <- 1
  get(paste0("subset.", x))[[get(paste0("matching.", x))$index.control, paste0("control.", x)]] <- 1
}

以下是运行最后三个命令时显示的错误。

> assign(get(paste0("subset.", x))[get(paste0("matching.", x))$index.control, paste0("control.", x)], 1)
Error in assign(get(paste0("subset.", x))[get(paste0("matching.", x))$index.control,  : 
  invalid first argument

> get(paste0("subset.", x))[get(paste0("matching.", x))$index.control, paste0("control.", x)] <- 1
Error in get(paste0("subset.", x))[get(paste0("matching.", x))$index.control,  : 
  target of assignment expands to non-language object

> get(paste0("subset.", x))[[get(paste0("matching.", x))$index.control, paste0("control.", x)]] <- 1
Error in get(paste0("subset.", x))[[get(paste0("matching.", x))$index.control,  : 
  target of assignment expands to non-language object

因此,我的目标是创建一个包含循环变量名称的新“虚拟”变量,并将 1 的值分配给它,其中行号与 get(paste0("matching.", x))$index.control 中的数字匹配。

【问题讨论】:

  • 使用get()assign() 通常表明你做错了(或以非常非R 的方式)。您可能应该使用命名列表来存储元素,而不是创建一堆变量。最好从对问题和所需输出的描述开始,而不是专注于您尝试如何做到这一点。
  • 请举例说明你想要什么;如果您必须每年进行测试,则需要进行拆分,并且我怀疑(以您的示例)您将拥有基于 20 个可能值的 index.control(但每年限制。作为 MrFlick highlitgjt,分配和获取在大多数情况下)不受欢迎的情况。我建议先看看split(df,df$year),它准备了一个包含每年存储的data.frame的列表。

标签: r loops


【解决方案1】:

考虑一个应用解决方案,您可以使用lapply 存储匹配的索引和子集数据帧,然后使用mapply 对它们运行所需的值操作。完成后,使用assign() 输出到多个对象。

# LIST OF YEARLY DATAFRAMES
subsetdfs <- lapply(2011:2013, function(x) df[df$year == x,])

# LIST OF YEARLY RANDOM IDS
matchinglists <- lapply(2011:2013, function(x) {
                                     set.seed(x)
                                     sample(1:20, 4)
                                  }
                        )

# USER-DEFINED FUNCTION TO ASSIGN NAMED COLUMN AND VALUE
dfprocess <- function(x, y){
                x['control'] <- NA
                x[y,'control'] <- 1
                x <- x[!is.na(x$id),]
                return(x)
             }

# MAPPLY TO MAP ITERATIVELY EACH LIST FOR FCT
dflist <- mapply(dfprocess, x=subsetdfs, y=matchinglists)
dflist    
#         [,1]      [,2]      [,3]     
# id      Integer,6 Integer,9 Integer,5
# year    Integer,6 Integer,9 Integer,5
# dum     Integer,6 Integer,9 Integer,5
# var     Integer,6 Integer,9 Integer,5
# test    Numeric,6 Numeric,9 Numeric,5
# control Numeric,6 Numeric,9 Numeric,5

# CREATE MULTIPLE FINAL DFS
for (i in 2011:2013) {
      assign(paste0('subset', i), 
             data.frame(dflist[, i - 2010]),
             envir = .GlobalEnv)
}

【讨论】:

    猜你喜欢
    • 2021-09-01
    • 2021-12-15
    • 2019-11-28
    • 2021-12-18
    • 2012-01-05
    • 1970-01-01
    • 2021-10-24
    • 2021-12-24
    • 1970-01-01
    相关资源
    最近更新 更多