【问题标题】:Split to list() based on condition, omiting the False elements根据条件拆分为 list(),省略 False 元素
【发布时间】:2019-01-28 21:50:44
【问题描述】:

根据条件将向量拆分为 n 个元素的最优雅方法是什么?

每个单独的真块都应该进入它自己的列表元素。所有虚假的元素都会被丢弃。

示例 1:

vec  <- c(1:3,NA,NA,NA,4:6,NA,NA,NA,7:9,NA)
cond <- !is.na(vec)

result = list(1:3,4:6,7:9)

示例 2:

vec_2  <- c(3:1,11:13,6:4,14:16,9:7,20)
cond_2 <- vec_2 < 10

results_2 = list(3:1,6:4,9:7)

如果有一个向量vec 和相关条件cond通用解决方案,那就太好了。

我最好的尝试:

res   <- split(vec,data.table::rleidv(cond))
odd  <- as.logical(seq_along(res)%%2)
res[if(cond[1])odd else !odd]

【问题讨论】:

    标签: r list vector split


    【解决方案1】:

    我想这应该可以正常工作:

    > split(vec[cond], data.table::rleid(cond)[cond])
    $`1`
    [1] 1 2 3
    
    $`3`
    [1] 4 5 6
    
    $`5`
    [1] 7 8 9
    

    让我们把它变成一个函数:

    > f <- function(vec, cond) split(vec[cond], data.table::rleid(cond)[cond])
    
    > f(vec_2, cond_2)
    $`1`
    [1] 3 2 1
    
    $`3`
    [1] 6 5 4
    
    $`5`
    [1] 9 8 7
    

    【讨论】:

      【解决方案2】:

      这是一个带有rlebase R 选项

      grp <- with(rle(cond), rep(seq_along(values) * NA^ !values, lengths))
      split(vec[cond], grp[cond])
      #$`1`
      #[1] 1 2 3
      
      #$`3`
      #[1] 4 5 6
      
      #$`5`
      #[1] 7 8 9
      

      与“vec_2”类似

      grp <- with(rle(cond_2), rep(seq_along(values) * NA^ !values, lengths))
      split(vec_2[cond_2], grp[cond_2])
      #$`1`
      #[1] 3 2 1
      
      #$`3`
      #[1] 6 5 4
      
      #$`5`
      #[1] 9 8 7
      

      或者用cumsumdiff创建一个分组变量

      grp <- cumsum(c(TRUE, diff(cond) < 0)) * NA^ is.na(vec)
      

      【讨论】:

      • 1up 使用NA^ 0
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-08-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-30
      • 1970-01-01
      相关资源
      最近更新 更多