2013-03-16 52 views
1

我想在現有數據框的列名稱上使用循環,然後基於舊列創建新列。這裏是我的示例數據:遍歷R中列的名稱以創建新列

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值的兩個變量= 0時,d = 1和值與d = 1時,d = 0(在這裏我其實不需要for loop,但對於我的原始數據集與大列(變量),我真的需要循環)基於以下條件:

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 

我將不勝感激在這方面您的寶貴意見。

回答

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])) 
} 

幾點意見:

  1. 取代names(sample[,1:2])更優雅colnames(sample)[1:2]
  2. $用於交互式使用。相反,在編程時,即,當被解釋的列名,你需要使用[[[,所以我換成sample$i.impsample[[paste0(i, '.impt')]]
  3. withi[D==0]不會給你x1[D==0]i"x1",因此需要使用get對其進行解引用。感謝您的解決方案:
  4. ,因爲它也是一個很常見的功能
+1

5.'帶'也是最好保存爲僅用於交互式使用 – baptiste

+1

6.這真的,真的是瘋了......你能解釋爲什麼你覺得需要這樣做嗎?我無法想象這是必要的情況 – alexwhan

+0

我同意你們倆。 @alexwhan,我希望你問OP,而不是我,對吧?! – flodel

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 
+0

@巴蒂斯特的名字你不應該命名data.frame sample。 – Metrics