拆分向量由n个零分成不同的组

d.b*_*d.b 9 r

我有一个矢量 x

x = c(1, 1, 2.00005, 1, 1, 0, 0, 0, 0, 1, 2, 0, 3, 4, 0, 0, 0, 0, 1, 2, 3, 1, 3)
Run Code Online (Sandbox Code Playgroud)

我需要将由n(在这种情况下,假设n3)或更多零分隔的值拆分为不同的组.

期望的输出将是

list(x1 = c(1, 1, 2.00005, 1, 1),
     x2 = c(1, 2, 0, 3, 4),
     x3 = c(1, 2, 3, 1, 3))
#$x1
#[1] 1.00000 1.00000 2.00005 1.00000 1.00000

#$x2
#[1] 1 2 0 3 4

#$x3
#[1] 1 2 3 1 3
Run Code Online (Sandbox Code Playgroud)

以下方法不起作用,因为x即使n组中的零数少于零,它也会分裂.

temp = cumsum(x == 0)
split(x[x!=0], temp[x!=0])
#$`0`
#[1] 1.00000 1.00000 2.00005 1.00000 1.00000

#$`4`
#[1] 1 2

#$`5`
#[1] 3 4

#$`9`
#[1] 1 2 3 1 3
Run Code Online (Sandbox Code Playgroud)

Ric*_*ven 6

这是我的尝试.该方法用NA替换长度小于或等于3的零游程.由于NA在使用时被移除split(),因此我们留下了所需的输出.

x <- c(1, 1, 2.00005, 1, 1, 0, 0, 0, 0, 1, 2, 0, 3, 4, 0, 0, 0, 0, 1, 2, 3, 1, 3)

ll <- with(rle(x == 0), {
  ifelse(x == 0 & (seq_along(x) != cumsum(lengths)[lengths <= 3 & values]), NA, x)
})

split(x, with(rle(is.na(ll)), rep(1:length(lengths), lengths) + ll * 0))
# $`1`
# [1] 1.00000 1.00000 2.00005 1.00000 1.00000
#
# $`3`
# [1] 1 2 0 3 4
#
# $`5`
# [1] 1 2 3 1 3
Run Code Online (Sandbox Code Playgroud)


lmo*_*lmo 5

下面是一个方法rle,splitlapply

# get RLE
temp <- rle(x)
# replace values with grouping variables
temp$values <- cumsum(temp$values == 0 & temp$lengths > 2)

# split on group and lapply through, dropping 0s at beginning which are start of each group
lapply(split(x, inverse.rle(temp)), function(y) y[cummax(y) > 0])
$`0`
[1] 1.00000 1.00000 2.00005 1.00000 1.00000

$`1`
[1] 1 2 0 3 4

$`2`
[1] 1 2 3 1 3
Run Code Online (Sandbox Code Playgroud)

没有的第二种方法lapply如下

# get RLE
temp <- rle(x)
# get positions of 0s that force grouping
changes <- which(temp$values == 0 & temp$lengths > 2)
# get group indicators
temp$values <- cumsum(temp$values == 0 & temp$lengths > 2)
# make 0s a new group
temp$values[changes] <- max(temp$values) + 1L

# create list
split(x, inverse.rle(temp))
$`0`
[1] 1.00000 1.00000 2.00005 1.00000 1.00000

$`1`
[1] 1 2 0 3 4

$`2`
[1] 1 2 3 1 3

$`3`
[1] 0 0 0 0 0 0 0 0
Run Code Online (Sandbox Code Playgroud)

最后,您只需删除最后一个列表项,例如head(split(x, inverse.rle(temp)), -1).