2014-05-01 70 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