我是Stata用户,试图切换到R并且通常会让初学者挣扎。我一直在尝试(并且失败)做了几天的循环,现在我投降了。 我想做什么(在一个循环中):
从变量名列表
创建一个新变量
根据现有变量的值重新编码新变量
可能使用dplyr语法这样做,但这不是必需的, 只是为了与我的其余代码保持一致。
这是我想要做的一个程式化的例子。在我的实际数据中,x.x和x.y变量源自应用于2个现有数据帧的连接函数。
N <- 1000
df <- data.frame(x1 = rnorm(N),
x2.x = rnorm(N)+2,x2.y = rnorm(N)-2,
x3.x = rnorm(N)+3,x3.y = rnorm(N)-3)
varlist <- c("x2","x3")
lapply(varlist, function(x) {
df <- df %>% mutate(x = ifelse(x1 < 0, paste0(x,".y"),paste0(x,".x")) # generate varialble "x" values from existing x.x and x.y
})
当我运行代码的lapply部分时,我收到错误消息
错误:意外'}'在: “df&lt; -df%&gt;%mutate(x = ifelse(x1&lt; 0,paste0(x,”。y“),paste0(x,”。x“))#从现有值生成变量”x“值xx和xy }“
即使它应该被预期......我确信我的代码中存在许多错误,这部分是因为我习惯于Stata中的宏,而R中没有直接的等价物。无论如何,如果你能指出我正确的方向,这将是太棒了!
答案 0 :(得分:3)
您的代码无效的原因是您的paste0(x, ".y")
确实将x
与.y
粘贴在一起。就是这样,您并没有告诉它按该列对数据进行分组。
您实际应该做的是根据paste0(x, ".y")
生成的列名对数据进行子集化。例如,要获取数据列x2.y
,您可以去
df[, paste0(varlist[1], ".y")]
## and of course the same can be done for second item of varlist
# df[, paste0(varlist[2], ".y")]
现在我们知道如何通过变量名称对列进行子集,并且因为您想要学习如何在循环中编写它,我们可以用varlist[1]
(和varlist[2]
)替换数字&#39;循环&#39;变量
以下是两种方法:一种是使用进行循环,另一种是使用 sapply
for(i in varlist){
df[, i] <- ifelse(df[, "x1"] < 0, df[, paste0(i, ".y")], df[, paste0(i, ".x")])
}
head(df)
# x1 x2.x x2.y x3.x x3.y x2 x3
# 1 -0.56047565 1.0042013 -2.5116037 2.849693 -2.8034502 -2.5116037 -2.803450
# 2 -0.23017749 0.9600450 -1.7630621 2.672243 -2.3498868 -1.7630621 -2.349887
# 3 1.55870831 1.9820198 -2.5415892 1.551835 -2.3289958 1.9820198 1.551835
# 4 0.07050839 1.8678249 -0.7807724 2.302715 -4.2841578 1.8678249 2.302715
# 5 0.12928774 -0.5493428 -1.8258641 5.598490 -5.0261096 -0.5493428 5.598490
# 6 1.71506499 3.0405735 -2.6152683 2.962585 -0.7946739 3.0405735 2.962585
您也可以使用*apply
执行此操作,在这种情况下,我使用sapply
,以便简化&#39;结果(而lapply
将返回列表)
df[, varlist] <- sapply(varlist, function(x){
ifelse(df[, "x1"] < 0, df[, paste0(x, ".y")], df[, paste0(x, ".x")])
})
head(df)
# x1 x2.x x2.y x3.x x3.y x2 x3
# 1 -0.56047565 1.0042013 -2.5116037 2.849693 -2.8034502 -2.5116037 -2.803450
# 2 -0.23017749 0.9600450 -1.7630621 2.672243 -2.3498868 -1.7630621 -2.349887
# 3 1.55870831 1.9820198 -2.5415892 1.551835 -2.3289958 1.9820198 1.551835
# 4 0.07050839 1.8678249 -0.7807724 2.302715 -4.2841578 1.8678249 2.302715
# 5 0.12928774 -0.5493428 -1.8258641 5.598490 -5.0261096 -0.5493428 5.598490
# 6 1.71506499 3.0405735 -2.6152683 2.962585 -0.7946739 3.0405735 2.962585
set.seed(123) ## setting the seed as we're sampling
N <- 1000
df <- data.frame(x1 = rnorm(N),
x2.x = rnorm(N)+2,x2.y = rnorm(N)-2,
x3.x = rnorm(N)+3,x3.y = rnorm(N)-3)
答案 1 :(得分:0)
答案 2 :(得分:0)
这对我有用:
lapply(varlist, function(x)
df <- df %>% mutate(x = ifelse(x1 < 0, paste0(x,".y"),paste0(x,".x")) # generate varialble "x" values from existing x.x and x.y
))
您不需要使用大括号来指定使用lapply
的循环。有关lapply
语法的详细信息,请Read this。