[英]R: looping through column names
我是Stata用户,尝试切换到R并进行常规的初学者奋斗。 我一直在尝试(但失败)做循环几天,现在我投降了。 我想做的事情(循环):
从变量名列表开始
创建一个新变量
根据现有变量的值重新编码该新变量
可能使用dplyr语法这样做,但这不是必需的,只是为了与我的其余代码保持一致。
这是我尝试做的一个程式化示例。 在我的实际数据中,xx和xy变量源自应用于2个现有数据帧的join函数。
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 <-df%>%mutate(x = ifelse(x1 <0,paste0(x,”。y“),paste0(x,”。x“))#生成变量x“来自现有xx和xy的值}”
即使可以预料到...我确信代码中存在许多错误,部分原因是因为我习惯于Stata中的宏,而R中没有直接等效的宏。无论如何,如果您能指出我的意思,正确的方向太棒了!
您的代码无法正常工作的原因是您的paste0(x, ".y")
实际上是使用.y
粘贴x
。 就是这样,您不是要告诉它按该列对数据进行子集化。
您实际上应该做的是根据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]
)中的数字替换为“ looping”变量
这有两种方法,一种使用for循环,另一种使用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
,以使其“简化”结果(而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)
这为我工作:
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
语法的更多信息。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.