获取重复#次的所有元素的索引的最佳方法是什么?我想确定重复两次以上的元素。
@Query
和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)
这些就是我需要的值。
有没有更合适的R功能?
本
答案 0 :(得分:9)
带有data.table的一个选项。当n = 2时,没有真正的理由使用它代替lag
/ shift
,但是对于较大的n,这可以避免创建大量新的滞后向量。
library(data.table)
which(rowid(rleid(t1)) > 2)
# [1] 4 11 12
说明:
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
编辑:如果像该问题所提出的示例那样,没有两个游程(甚至是长度为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
答案 1 :(得分:6)
您可以使用dplyr::lag
或data.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
如果您需要它来缩放几个副本,则可以执行以下操作(感谢提示@IceCreamToucan):
n <- 2
df1 <- sapply(0:n, function(x) shift(t1, x))
which(rowMeans(df1 == df1[,1]) == 1)
[1] 4 11 12
答案 2 :(得分:2)
通常rle
是有用的情况,即
v1 <- rle(t1)
i1 <- seq_along(t1)[t1 %in% v1$values[v1$lengths > 2]]
i2 <- t1[t1 %in% v1$values[v1$lengths > 2]]
tapply(i1, i2, function(i) tail(i, -2))
#$`8`
#[1] 11 12
#$`10`
#[1] 4
您可以取消列表并将其作为矢量,
unlist(tapply(i1, i2, function(i) tail(i, -2)))
#81 82 10
#11 12 4
rleid
包中还有一个名为data.table
的函数可供我们使用,
unlist(lapply(Filter(function(i) length(i) > 2, split(seq_along(t1), data.table::rleid(t1))),
function(i) tail(i, -2)))
#2 71 72
#4 11 12
答案 3 :(得分:2)
涉及rle()
的另一种可能性可能是:
pseudo_rleid <- with(rle(t1), rep(seq_along(values), lengths))
which(ave(t1, pseudo_rleid, FUN = function(x) seq_along(x) > 2) != 0)
[1] 4 11 12