R 嵌套的ifelse语句,具有编程数量的嵌套级别

R 嵌套的ifelse语句,具有编程数量的嵌套级别,r,R,我有一个3列的矩阵。对于每一行,应选择一个非缺失值,-如果在第1列中未找到值,将搜索第2列,然后搜索第3列,并由用户给出顺序 我对我的复杂嵌套的ifelse方法相当满意——唉,这取决于给定列的相同长度。但是列的数量应该是灵活的(因此嵌套的ifelse语句的数量应该是灵活的)——这意味着,如果用户只选择了一列或两列,即使不需要的列包含一个值,也会导致NA foo_mat[1,]NA 100 2 #>[2,]3087 NA #>[3,]15 NA 10 #> [4,] 0 0 0 #>[5,

我有一个3列的矩阵。对于每一行,应选择一个非缺失值,-如果在第1列中未找到值,将搜索第2列,然后搜索第3列,并由用户给出顺序

我对我的复杂嵌套的
ifelse
方法相当满意——唉,这取决于给定列的相同长度。但是列的数量应该是灵活的(因此嵌套的ifelse语句的数量应该是灵活的)——这意味着,如果用户只选择了一列或两列,即使不需要的列包含一个值,也会导致NA

foo_mat[1,]NA 100 2
#>[2,]3087 NA
#>[3,]15 NA 10
#> [4,]  0   0  0
#>[5,]NA-NA-NA
foo(foo_mat,c(“a”、“c”、“b”))
#>[1]230150 NA
foo(foo_mat,precd=c(“b”,“a”))
#>x[,preced[3]]中的错误:下标超出边界#(当然)
#期望输出
#>[1]100 87 15 0 NA

与其使用嵌套的
ifelse
,不如使用
合并创建函数

foo <- function(data, preced) {
        do.call(dplyr::coalesce, as.data.frame(data[, preced]))
       }


foo(foo_mat, c("a", "c", "b"))
#[1]  2 30 15  0 NA
foo(foo_mat, c("b", "a"))
#[1] 100  87  15   0  NA
基准R:

apply(foo_mat[,c(“a”,“c”,“b”)]),1,函数(z)c(na.省略(z),na)[1])
#[1]230150 NA
anon函数是一个两步过程:

  • 首先,删除任何
    NA
    s,这样我们就可以获取第一个非
    NA
  • 其次,
    na.ommit(.)
    将返回
    整数(0)
    ,这不是您想要的,因此
    c(,na)[1]
    确保在
    na.ommit(.)
    之后,
    c(.)
    向量中始终至少有一个值,并且我们想要第一个值;如果
    na.ommit
    不返回任何内容,那么至少我们有一个
    na
使用
apply(foo_mat,1,…)
按行执行此操作。您可以通过重新排列进入
apply
数据的列来控制首选项顺序,就像我使用
foo_mat[,c(“a”,“c”,“b”)]
一样

作为一项功能:


foo这里有一个函数
foo
,它可以根据所发布的示例的需要工作

foo <- function(x, preced){
  apply(x[, preced], 1, function(y){
    w <- !is.na(y)
    if(any(w)) y[w][1] else NA
  })
}

foo(foo_mat, c("a", "c", "b"))
#[1]  2 30 15  0 NA
foo(foo_mat, preced = c("b", "a"))
#[1] 100  87  15   0  NA

foo您的示例数据是一个良好的开端,但缺少最后一部分。我想它需要添加
“b”,“c”)
,对吗?我的错,谢谢你看到它。。。但我的鼠标拖动复制/粘贴并没有抓到它,所以不管怎样,一起编辑它可能会很有用。谢谢,很抱歉发出噪音。仅供参考,@RuiBarradas提供的答案提供了相同的结果。但是在这种大小的数据上,这个函数的速度是原来的两倍多。我认为
c(z[!is.na(z)],na)[1]
甚至可以写
z[!is.na(z)][1]
,因为
整数(0)[1]
na
foo <- function(x, preced){
  apply(x[, preced], 1, function(y){
    w <- !is.na(y)
    if(any(w)) y[w][1] else NA
  })
}

foo(foo_mat, c("a", "c", "b"))
#[1]  2 30 15  0 NA
foo(foo_mat, preced = c("b", "a"))
#[1] 100  87  15   0  NA