2014-05-01 68 views
0

我有以下data.frameifelse基於以下幾個條件

a <- c(26, 26, 156, 801, 143, 4, 455, 446, 447, 241, 461, 343, 359, 409, 241) 
b <- c(26, 26, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA) 
c <- c(NA, NA, NA, NA, NA, 4, NA, NA, NA, NA, NA, NA, NA, NA, NA) 
d <- c(NA, NA, NA, NA, NA, NA, NA, 446, 447, NA, 461, NA, NA, NA, NA) 

test <- data.frame(a,b,c,d) 

我希望得到基於在test$btest$ctest$d值的下一個矢量e。我還是習慣在Excel中,如果命令,所以我想這:

test$e <- ifelse(is.na(b)==TRUE, ifelse(is.na(c)==TRUE, ifelse(is.na(d)==TRUE)), test$a, NA) 

test$e <- ifelse(is.na(b)==TRUE && is.na(c)==TRUE && is.na(d)==TRUE, test$a, NA) 

顯然沒有奏效。我敢肯定,這可能不會太困難,test看起來應該是這樣算賬:

a b c d e 
1 26 26 NA NA NA 
2 26 26 NA NA NA 
3 156 NA NA NA 156 
4 801 NA NA NA 801 
5 143 NA NA NA 143 
6 4 NA 4 NA NA 
7 455 NA NA NA 455 
8 446 NA NA 446 NA 
9 447 NA NA 447 NA 
10 241 NA NA NA 241 
11 461 NA NA 461 NA 
12 343 NA NA NA 343 
13 359 NA NA NA 359 
14 409 NA NA NA 409 
15 241 NA NA NA 241 

什麼是ifelse做到這一點的正確方法以及是否有其他(也許更簡單)的方式? 謝謝!

回答

2

只要用唱&,它作爲布爾和向量:

test$e <- with(test, ifelse(is.na(b) & is.na(c) & is.na(d), a, NA)) 

注之差&&&操作:a && b由標量布爾值,並有內置的快捷方式:如果a已經是假的,b根本不會被評估。另一方面,a & b保證評估ab,並對矢量進行處理。

有很多方法可以使你所描述的選擇。 Richard Scrivens的answer是另一種可能性。在R中經常出現的最好的選擇是風格問題。就我個人而言,現在我找到最具吸引力的解決方案,因爲它明確了它的功能,並且不需要其中一種更加奇特的功能。但是,如果有10個但不是三個條目,我肯定會更喜歡另一種方式。

+0

這工作完美,謝謝。 – Thomas

+0

嗯..該方法給了我所有的新手,奇怪的... –

+3

請注意,你不需要== TRUE部分,因爲is.na已經返回一個邏輯值。 – Dason

2

你基本上只改變三個NA值的那些行,因此我們可以在if語句中使用
sum(is.na(...)) == 3

## this way is a bit slower than using rowSums() 
> test$e <- ifelse(apply(test, 1, function(x) sum(is.na(x))) == 3, test$a, NA) 

正如flodel所示,rowSums可能是更好,更快的路線。

> test$e <- ifelse(rowSums(is.na(test[c("b", "c", "d")])) == 3, test$a, NA) 
> test 
##  a b c d e 
## 1 26 26 NA NA NA 
## 2 26 26 NA NA NA 
## 3 156 NA NA NA 156 
## 4 801 NA NA NA 801 
## 5 143 NA NA NA 143 
## 6 4 NA 4 NA NA 
## 7 455 NA NA NA 455 
## 8 446 NA NA 446 NA 
## 9 447 NA NA 447 NA 
## 10 241 NA NA NA 241 
## 11 461 NA NA 461 NA 
## 12 343 NA NA NA 343 
## 13 359 NA NA NA 359 
## 14 409 NA NA NA 409 
## 15 241 NA NA NA 241 
+0

你也應該用'test [c(「b」,「c」,「d」)]'代替'test'。 (這些關於數據的假設是危險的,例如嘗試運行代碼兩次。) – flodel