gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-03 18:39:32 25 4
gpt4 key购买 nike

我有一个 3 列的矩阵。对于每一行,应选择一个非缺失值, - 如果在第 1 列中未找到任何值,则将搜索第 2 列,然后搜索第 3 列,并由用户给出顺序。
我对我复杂的嵌套 ifelse 方法相当满意 - 唉,这取决于给定列的相同长度。但是列的数量应该是灵活的(因此嵌套 ifelse 语句的数量是灵活的) - 意思是,如果用户只选择一两列,即使不需要的列包含一个值,也会产生 NA。

foo_mat <- structure(c(
NA, 30L, 15, 0, NA, 100L, 87L, NA, 0, NA, 2L, NA,
10, 0, NA
), .Dim = c(5L, 3L), .Dimnames = list(NULL, c(
"a", "b", "c"
)))

foo <- function(x, preced) {
ifelse(!is.na(x[, preced[1]]), x[, preced[1]],
ifelse(!is.na(x[, preced[2]]), x[, preced[2]],
x[, preced[3]]
)
)
}

foo_mat
#> a b c
#> [1,] NA 100 2
#> [2,] 30 87 NA
#> [3,] 15 NA 10
#> [4,] 0 0 0
#> [5,] NA NA NA

foo(foo_mat, c("a", "c", "b"))
#> [1] 2 30 15 0 NA

foo(foo_mat, preced = c("b", "a"))
#> Error in x[, preced[3]]: subscript out of bounds #(of course)

# desired output
#> [1] 100 87 15 0 NA

最佳答案

基础 R:

apply(foo_mat[,c("a","c","b")], 1, function(z) c(na.omit(z), NA)[1])
# [1] 2 30 15 0 NA
anon-function 是一个两步过程:
  • 首先,删除所有 NA s,以便我们可以获取第一个非 NA
  • 第二, na.omit(.) 返回 integer(0) 是可行的,这不是你想要的,所以 c(., NA)[1] 确保在 na.omit(.) 之后,我们总是在 c(.) 向量中至少有一个值,我们想要第一个;如果 na.omit 什么都不返回,那么至少我们有一个 NA

  • 使用 apply(foo_mat, 1, ...) 逐行执行此操作。您可以通过重新排列进入 apply 数据的列来控制偏好顺序,就像我使用 foo_mat[,c("a","c","b")] 一样。
    作为一个函数:
    foo <- function(data, preced = names(data)) apply(data[,preced,drop=FALSE], 1, function(z) c(na.omit(z), NA)[1])
    foo(foo_mat, c("a", "c", "b"))
    # [1] 2 30 15 0 NA
    ( drop=FALSE 是防御性的。基础 R 默认 foo_mat[,"a"] 的行为是一个向量而不是一个 1 列矩阵。这破坏了很多东西,包括 apply 。所以添加 drop=FALSE 可以防止默认的减少行为。)
    与其他答案一样快的替代方案:
    foo <- function(data, preced) apply(data[,preced,drop=FALSE], 1, function(z) z[!is.na(z)][1])
    相同的功能,更少的调用,简单的逻辑。
    (归因:这个替代方案是@tmfmnk、@Tjebo 和我的工作的结合。谢谢!)

    关于r - 嵌套 ifelse 语句,具有编程数量的嵌套级别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65431065/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com