我有以下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)
我希望根据e
,test$b
和test$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
执行此操作的正确方法是什么?还有其他(可能更简单)方法吗?
谢谢!
答案 0 :(得分:2)
只需使用作为布尔值的矢量&
和矢量:
test$e <- with(test, ifelse(is.na(b) & is.na(c) & is.na(d), a, NA))
请注意&&
和&
运算符之间的区别:a && b
是针对标量布尔值的,并且内置了快捷方式:如果a
已经为假,{ {1}}根本不会被评估。另一方面,b
可以保证评估a & b
和a
并对向量进行处理。
有很多方法可以进行您所描述的选择。 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