如何创建名称包含变量名称的新列(在循环中)?
问题描述:
我有一个包含行索引号的向量,我想根据这些数字创建一个新的虚拟变量,即向量中存在的行在新变量中的值为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
}
下面是runnig最后三个命令时显示的错误。
> 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
中的编号不一致。
答
考虑一个应用解决方案,您可以使用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)
}
使用'get()'和'assign()'通常表示你做错了事(或者以非R的方式)。您可能应该使用命名列表来存储元素,而不是创建一堆变量。最好从问题描述和期望的输出开始,而不是专注于你如何尝试去做。 – MrFlick
请举例说明你想要什么;如果你不得不每年测试一次,我会怀疑(你的例子)你会有index.control基于20个可能的值(但是限制每年)。作为MrFlick highlitgjt,分配和获取最多我不建议这样做,我建议首先查看'split(df,df $ year)',它可以为存储的每年data.frame准备一个列表。 –