我正在尝试在现有数据框的列名上使用循环,然后根据旧列之一创建新列。这是我的示例数据:
sample<-list(c(10,12,17,7,9,10),c(NA,NA,NA,10,12,13),c(1,1,1,0,0,0))
sample<-as.data.frame(sample)
colnames(sample)<-c("x1","x2","D")
>sample
x1 x2 D
10 NA 1
12 NA 1
17 NA 1
7 10 0
9 20 0
10 13 0
现在,我正在尝试使用for loop
生成两个变量x1.imp和x2.imp,当D = 1时,其值与D = 0相关,当D = 0时,与D = 1相关的值(这里我实际上不需要for loop
但是对于我的原始数据集有大cols(变量),我真的需要循环)基于以下条件:
for (i in names(sample[,1:2])){
sample$i.imp<-with (sample, ifelse (D==1, i[D==0],i[D==1]))
i=i+1
return(sample)
}
Error in i + 1 : non-numeric argument to binary operator
但是,以下工作,但它不会将新cols的名称设为imp.x2和imp.x3
for(i in sample[,1:2]){
impt.i<-with(sample,ifelse(D==1,i[D==0],i[D==1]))
i=i+1
print(as.data.frame(impt.i))
}
impt.i
1 7
2 9
3 10
4 10
5 12
6 17
impt.i
1 10
2 12
3 13
4 NA
5 NA
6 NA
请注意,我已经知道没有循环 [here]的解决方案。我想要循环。
预期产出:
x1 x2 D x1.impt x2.imp
10 NA 1 7 10
12 NA 1 9 20
17 NA 1 10 13
7 10 0 10 NA
9 20 0 12 NA
10 13 0 17 NA
我非常感谢您在这方面的宝贵意见。
答案 0 :(得分:3)
这很疯狂,但是因为你要求它......你的代码变化最小的是:
for (i in colnames(sample)[1:2]){
sample[[paste0(i, '.impt')]] <- with(sample, ifelse(D==1, get(i)[D==0],get(i)[D==1]))
}
一些评论:
names(sample[,1:2])
替换为更优雅的colnames(sample)[1:2]
$
用于交互式使用。相反,在编程时,即要解释列名时,您需要使用[
或[[
,因此我将sample$i.imp
替换为sample[[paste0(i, '.impt')]]
with
内,i[D==0]
在x1[D==0]
为i
时不会向您"x1"
,因此需要使用get
取消引用它。 sample
命名,因为它也是一个非常常见的函数的名称答案 1 :(得分:1)
这应该有效,
test <- sample[,"D"] == 1
for (.name in names(sample)[1:2]){
newvar <- paste(.name, "impt", sep=".")
sample[[newvar]] <- ifelse(test, sample[!test, .name],
sample[test, .name])
}
sample