ifelse基于几个条件

时间:2014-05-01 11:11:22

标签: r if-statement

我有以下data.frame

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)

我希望根据etest$btest$c中的值获取下一个向量test$d。我仍然习惯于excel中的if-command,因此我尝试了这个:

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 个答案:

答案 0 :(得分:2)

只需使用作为布尔值的矢量&和矢量:

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

请注意&&&运算符之间的区别:a && b是针对标量布尔值的,并且内置了快捷方式:如果a已经为假,{ {1}}根本不会被评估。另一方面,b可以保证评估a & ba并对向量进行处理。

有很多方法可以进行您所描述的选择。 Richard Scrivens的answer是另一种可能性。在R中经常出现的最佳选择是风格问题。就个人而言,我现在发现最具吸引力的b解决方案,因为它清楚地知道它的作用,并且不需要其中一个更奇特的功能。但是,如果有10个而不是3个条目,我肯定会选择其他方式。

答案 1 :(得分:2)

您基本上只更改了具有三个NA值的行,因此我们可以使用
 sum(is.na(...)) == 3声明中的if

  ## 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