索引向量中的连续重复项

Ben*_*ers 7 r vector

获取重复#次的所有元素的索引的最佳方法是什么?我想确定重复两次以上的元素。 rle()rleid()这两种提示我需要的值,但既不方法是直接给我的指标。

我想出了以下代码:

t1 <- c(1, 10, 10, 10, 14, 37, 3, 14, 8, 8, 8, 8, 39, 12)

t2 <- lag(t1,1)
t2[is.na(t2)] <- 0
t3 <- ifelse(t1 - t2 == 0, 1, 0)
t4 <- rep(0, length(t3))
for (i in 2:length(t3)) t4[i] <- ifelse(t3[i] > 0, t3[i - 1] + t3[i], 0)

which(t4 > 1)
Run Code Online (Sandbox Code Playgroud)

返回:

[1]  4 11 12 
Run Code Online (Sandbox Code Playgroud)

这些就是我需要的价值观。

是否有更合适的R功能?

Ice*_*can 8

data.table的一种选择。当n = 2时,没有真正的理由使用它代替lag/ shift,但是对于较大的n,这将使您免于创建大量新的滞后向量。

library(data.table)

which(rowid(rleid(t1)) > 2)
# [1]  4 11 12
Run Code Online (Sandbox Code Playgroud)

说明:

rleid将为相等值的每个“运行”产生唯一的值,rowid并将标记每个元素“进入”运行有多少个元素。您需要的是将2个以上的元素“放入”运行。

data.table(
  t1,
  rleid(t1),
  rowid(t1))

#     t1 V2 V3
#  1:  1  1  1
#  2: 10  2  1
#  3: 10  2  2
#  4: 10  2  3
#  5: 14  3  1
#  6: 37  4  1
#  7:  3  5  1
#  8: 14  6  2
#  9:  8  7  1
# 10:  8  7  2
# 11:  8  7  3
# 12:  8  7  4
# 13: 39  8  1
# 14: 12  9  1
Run Code Online (Sandbox Code Playgroud)

编辑:如果,如本问题所示的示例中,没有两个游程(甚至长度为1的“游程”)具有相同的值(或者如果您不在乎重复项是否彼此相邻),则可以使用which(rowid(t1) > 2)代替。(这是弗兰克在评论中指出的)

希望这个例子可以澄清差异

a <- c(1, 1, 1, 2, 2, 1)
which(rowid(a) > 2)
# [1] 3 6
which(rowid(rleid(a)) > 2)
# [1] 3
Run Code Online (Sandbox Code Playgroud)

  • 至少在OP的示例中,不需要rleid`which(data.table :: rowid(t1)&gt; 2)也会给出正确的结果。(...我不确定OP的“连续”是重复多次还是立即重复) (3认同)

And*_*rew 6

您可以使用dplyr::lagdata.table::shift(请注意,默认设置为shift滞后,因此shift(t1, 1)等于shift(t1, 1, type = "lag")

which(t1 == lag(t1, 1) & lag(t1, 1) == lag(t1, 2))
[1]  4 11 12
# Or
which(t1 == shift(t1, 1) & shift(t1, 1) == shift(t1, 2))
[1]  4 11 12
Run Code Online (Sandbox Code Playgroud)

如果需要扩展几个副本,可以执行以下操作(感谢@IceCreamToucan提示):

n <- 2
df1 <- sapply(0:n, function(x) shift(t1, x))
which(rowMeans(df1 == df1[,1]) == 1)
[1]  4 11 12
Run Code Online (Sandbox Code Playgroud)