将向量分解为列表的一般方法是什么?

use*_*361 1 r function list vector repeat

假设我们有一个向量:

x <- c(1,1,1,2,2,2,2,2,4,4,2,2,2,2)
Run Code Online (Sandbox Code Playgroud)

什么是可以采取x和返回的功能l,在哪里l等于

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

A5C*_*2T1 6

使用rle,rep以及split:

a <- rle(x)
split(x, rep(seq_along(a$lengths), a$lengths))
# $`1`
# [1] 1 1 1
#
# $`2`
# [1] 2 2 2 2 2
#
# $`3`
# [1] 4 4
# 
# $`4`
# [1] 2 2 2 2
Run Code Online (Sandbox Code Playgroud)

在此,rle计算输入向量的"运行长度".结果是listlengthsvalues.我们只需要lengths从中创建一个"分组"变量,我们可以在其上创建split原始矢量.


更新:更大向量的基准

我没有对while循环进行基准测试,因为使用这个长向量需要很长时间才能完成.

library(microbenchmark)
set.seed(1)
x <- sample(1:5, 1e5, replace = TRUE)
fun1 <- function() {
  a <- rle(x)
  split(x, rep(seq_along(a$lengths), a$lengths))
}
fun2 <- function() {
  splits = which(diff(x) != 0)
  split.locs = rbind(c(1, splits+1), c(splits, length(x)))
  apply(split.locs, 2, function(y) x[y[1]:y[2]])
}
fun3 <- function() split(x, c(0, cumsum(as.logical(diff(x)))))

microbenchmark(fun1(), fun2(), fun3(), times = 20)
# Unit: milliseconds
#    expr      min       lq   median       uq      max neval
#  fun1() 142.0386 147.7061 154.2853 158.0239 196.4665    20
#  fun2() 363.5707 386.0575 423.1791 444.4695 543.9427    20
#  fun3() 305.5331 316.0356 320.5203 329.7177 376.3236    20
Run Code Online (Sandbox Code Playgroud)