在R中将向量分割,每当向量元素发生更改时

3
我需要分割一个由重复元素组成的向量,每当元素值发生变化时都要进行分割。例如:
test_vector <- c("string1", "string1", "string1", "string2", 
  "string2", "string1", "string1", "string3")

must become:

$`1`
[1] "string1" "string1" "string1"

$`2`
[1] "string2" "string2"

$`3`
[1] "string1" "string1"

$`4`
[1] "string3"

如果我尝试使用split(test_vector, test_vector),会得到错误的输出:
$string1
[1] "string1" "string1" "string1" "string1" "string1"

$string2
[1] "string2" "string2"

$string3
[1] "string3"

我写了一些代码来实现这个功能,但似乎代码过长,感觉有更简单的方法我没发现:

# find indices where splitting will occur:
split_points <- rep(F, length(test_vector))
for (i in 1:length(test_vector)) {
  if (i != 1) {
    if (test_vector[i] != test_vector[i-1]) {
      split_points[i] <- T
    }
  }
}
split_points <- c(1, which(split_points))

# create split vector:
split_code <- rep(1, length(test_vector))
for ( j in 1:length(split_points) ) {

  if (j!=length(split_points)) {
    split_code[
      split_points[j]:(split_points[j+1]-1)
    ] <- j
  } else {
    split_code[
      split_points[j]:length(test_vector)
    ] <- j
  }

}

split_result <- split(test_vector, split_code)
$`1`
[1] "string1" "string1" "string1"

$`2`
[1] "string2" "string2"

$`3`
[1] "string1" "string1"

$`4`
[1] "string3"

如果有人能够帮助我找到一个更简单的解决方案,那将不胜感激!

1
尝试使用split(v1, rleid(v1))或在基础R中使用with(rle(v1), rep(seq_along(values), lengths)) - akrun
1
非常感谢您的答案,我喜欢rleid的简洁性。 - torpzorrr
抱歉,我很新,不知道怎么做,请问您能告诉我吗? - torpzorrr
啊,抱歉,我之前没有看到你下面的回答,还有评论。 - torpzorrr
没问题,谢谢。 - akrun
3个回答

1
base R 中,我们可以使用 rle 函数获取向量的运行长度编码。
grp <- with(rle(test_vector), rep(seq_along(values), lengths))

使用该方法来 split 向量。
split(test_vector, grp)

使用 data.tablerleid 根据相邻元素之间的差异给出 ID。

library(data.table)
split(test_vector, rleid(test_vector))

1
f = cumsum(c(TRUE, test_vector[-length(test_vector)] != test_vector[-1]))
split(test_vector, f)

或者

with(rle(test_vector), Map(rep, values, lengths))

0

一个基本的 R 选项是使用 findInterval + cumsum + rle,即

res <- split(test_vector,
             findInterval(seq_along(test_vector),
                          cumsum(rle(test_vector)$lengths),
                          left.open = TRUE))

such that

> res
$`1`
[1] "string1" "string1" "string1"

$`2`
[1] "string2" "string2"

$`3`
[1] "string1" "string1"

$`4`
[1] "string3"

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