R 基于不同优先级条件的嵌套ifelse替代方案
我想根据其他几个向量的条件创建一个向量。这些条件按优先级的降序排列。这里是一个简单的例子,我正在创建变量“see1”,它应该包含不同的字母,但不包含NA。创建它的优先级是分层的:l1>l2>l3>l4。例如,如果所有其他条件均为NA,则只能将“see1”的状态指定为“l4”;如果“l1”不为NA,则将自动将“l1”的状态指定为“l1”。l1将否决其他列。我使用了嵌套的ifelse来创建“see1”R 基于不同优先级条件的嵌套ifelse替代方案,r,R,我想根据其他几个向量的条件创建一个向量。这些条件按优先级的降序排列。这里是一个简单的例子,我正在创建变量“see1”,它应该包含不同的字母,但不包含NA。创建它的优先级是分层的:l1>l2>l3>l4。例如,如果所有其他条件均为NA,则只能将“see1”的状态指定为“l4”;如果“l1”不为NA,则将自动将“l1”的状态指定为“l1”。l1将否决其他列。我使用了嵌套的ifelse来创建“see1” test <- data.frame(id=c("a","b","c","d","e","f
test <- data.frame(id=c("a","b","c","d","e","f"),
l1=c(NA,NA,"A",NA,"B", NA),
l2=c(NA,NA,"N","N",NA,NA),
l3=c("V",NA,NA,NA,"V","V"),
l4=c("H","H",NA,NA,rep("H",2)), stringsAsFactors=F)
test$see1 <- ifelse(test$l1%in%c("A", "B"), test$l1,
ifelse(test$l2%in%"N", "N",
ifelse(test$l3%in%"V", "V",
ifelse(test$l4%in%"H","H", NA))))
test
id l1 l2 l3 l4 see1
1 a <NA> <NA> V H V
2 b <NA> <NA> <NA> H H
3 c A N <NA> <NA> A
4 d <NA> N <NA> <NA> N
5 e B <NA> V H B
6 f <NA> <NA> V H V
但是,由于有许多条件/列,此任务变得很麻烦。我已扫描了有关“嵌套ifelse”的类似问题,但没有遇到此问题。您可以尝试在l\\d”列上使用带有ties.method='first'的max.col创建列索引。cbindwith1:nrowtest`根据行/列索引从“测试”数据集的子集提取元素
nm <- grep('^l\\d+', names(test))
test[nm][cbind(1:nrow(test), max.col(!is.na(test[nm]), 'first'))]
#[1] "V" "H" "A" "N" "B" "V"
您可以在l\\d'列上尝试max.col with ties.method='first'来创建列索引。cbindwith1:nrowtest`根据行/列索引从'test'数据集的子集提取元素
nm <- grep('^l\\d+', names(test))
test[nm][cbind(1:nrow(test), max.col(!is.na(test[nm]), 'first'))]
#[1] "V" "H" "A" "N" "B" "V"
以下是凝聚解决方案: 首先,在我的示例中,对测试中的列重新排序并不是必需的,因为列已排序,但在其他情况下可能很重要
require(dplyr)
require(magrittr) # for piping
test %<>% select(l1,l2, l3, l4)
现在使用合并函数
coalesce2 <- function(...){
Reduce(function(x,y) {
i<-which(is.na(x))
x[i]<-y[i]
x},
list(...))
}
test$see1 <- coalesce2(test$l1,test$l2, test$l3, test$l4)
test
或者在magrittr软件包的帮助下
require(magrittr)
test$see1 <- test%$% coalesce2(l1,l2, l3, l4)
test
> l1 l2 l3 l4 see1
>1 <NA> <NA> V H V
>2 <NA> <NA> <NA> H H
>3 A N <NA> <NA> A
>4 <NA> N <NA> <NA> N
>5 B <NA> V H B
>6 <NA> <NA> V H V
以下是凝聚解决方案: 首先,在我的示例中,对测试中的列重新排序并不是必需的,因为列已排序,但在其他情况下可能很重要
require(dplyr)
require(magrittr) # for piping
test %<>% select(l1,l2, l3, l4)
现在使用合并函数
coalesce2 <- function(...){
Reduce(function(x,y) {
i<-which(is.na(x))
x[i]<-y[i]
x},
list(...))
}
test$see1 <- coalesce2(test$l1,test$l2, test$l3, test$l4)
test
或者在magrittr软件包的帮助下
require(magrittr)
test$see1 <- test%$% coalesce2(l1,l2, l3, l4)
test
> l1 l2 l3 l4 see1
>1 <NA> <NA> V H V
>2 <NA> <NA> <NA> H H
>3 A N <NA> <NA> A
>4 <NA> N <NA> <NA> N
>5 B <NA> V H B
>6 <NA> <NA> V H V
特别是在这个示例中,使用第一个非NA值替换NA,您要查找的操作称为SQL中的coalesce。谢谢你,格雷戈!那有帮助!我已经发布了下面的解决方案。特别是在这个示例中,使用第一个非NA值替换NA,您正在寻找的操作称为SQL中的coalesce。谢谢你,格雷戈!那有帮助!我已经在下面发布了解决方案。