looping over the name of the columns in R for creating new columns

匿名 (未验证) 提交于 2019-12-03 09:14:57

问题:

I am trying to use the loop over the column names of the existing dataframe and then create new columns based on one of the old column.Here is my sample data:

 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 

Now, I am trying to use for loop to generate two variables x1.imp and x2.imp that have values related to D=0 when D=1 and values related to D=1 when D=0(Here I actually don't need for loop but for my original dataset with large cols (variables), I really need the loop) based on the following condition:

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 

However, the following works, but it doesn't give the names of new cols as imp.x2 and 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 

Note that I already know the solution without loop [here]. I want with loop.

Expected output:

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 

I would greatly appreciate your valuable input in this regard.

回答1:

This is nuts, but since you are asking for it... Your code with minimum changes would be:

for (i in colnames(sample)[1:2]){   sample[[paste0(i, '.impt')]] <- with(sample, ifelse(D==1, get(i)[D==0],get(i)[D==1])) } 

A few comments:

  1. replaced names(sample[,1:2]) with the more elegant colnames(sample)[1:2]
  2. the $ is for interactive usage. Instead, when programming, i.e. when the column name is to be interpreted, you need to use [ or [[, hence I replaced sample$i.imp with sample[[paste0(i, '.impt')]]
  3. inside with, i[D==0] will not give you x1[D==0] when i is "x1", hence the need to dereference it using get.
  4. you should not name your data.frame sample as it is also the name of a pretty common function


回答2:

This should work,

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 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!