R 嵌套的ifelse语句,具有编程数量的嵌套级别
我有一个3列的矩阵。对于每一行,应选择一个非缺失值,-如果在第1列中未找到值,将搜索第2列,然后搜索第3列,并由用户给出顺序 我对我的复杂嵌套的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,
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