根据条件拆分为列表(list()),省略假元素。

4

最优雅的方式是基于条件将向量分割成n个元素。

每个独立的true块应该进入自己的列表元素。所有的false元素都被丢弃。

例子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]
2个回答

5
我猜这通常应该可行:
> 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

1
这是一个涉及编程的基于 base R 选项,使用了 rle 函数。
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)

1
使用 NA^ 0 得到了1分。 - Andre Elrico

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接