使用数据提取滚动基础上的累积唯一值(重置和恢复)。表R

使用数据提取滚动基础上的累积唯一值(重置和恢复)。表R,r,data.table,R,Data.table,给定data.table,我想提取累积唯一元素,直到它达到三个唯一值,然后重置并恢复: y <- data.table(a=c(1, 2, 2, 3, 3, 4, 3, 2, 2, 5, 6, 7, 9, 8)) 因为它递归地引用,我真的被绊倒了。。。真实数据很大,因此data.table解决方案会很好。我想不出任何方法可以从本质上避免for循环,除了将其隐藏在Reduce调用后面。我的逻辑是保持并集-在每一行上对每个新值进行赋值,直到集合增长到长度==n,此时新值将用作循环下一次迭代的

给定data.table,我想提取累积唯一元素,直到它达到三个唯一值,然后重置并恢复:

y <- data.table(a=c(1, 2, 2, 3, 3, 4, 3, 2, 2, 5, 6, 7, 9, 8))

因为它递归地引用,我真的被绊倒了。。。真实数据很大,因此data.table解决方案会很好。

我想不出任何方法可以从本质上避免
for
循环,除了将其隐藏在
Reduce
调用后面。我的逻辑是保持
并集
-在每一行上对每个新值进行赋值,直到集合增长到
长度==n
,此时新值将用作循环下一次迭代的起点

unionlim <- function(x, y, n=4) {
  u <- union(x,y)
  if(length(u) == n) y else u
}

y[, out := sapply(Reduce(unionlim, a, accumulate=TRUE), paste, collapse=" ")]

#    a   out
# 1: 1     1
# 2: 2   1 2
# 3: 2   1 2
# 4: 3 1 2 3
# 5: 3 1 2 3
# 6: 4     4
# 7: 3   4 3
# 8: 2 4 3 2
# 9: 2 4 3 2
#10: 5     5
#11: 6   5 6
#12: 7 5 6 7
#13: 9     9
#14: 8   9 8

unionlim也在这里工作

y$b <- accumulate(y$a, ~if(length(union(.x, .y)) == 4) .y else union(.x, .y))

 y
   a       b
1  1       1
2  2    1, 2
3  2    1, 2
4  3 1, 2, 3
5  3 1, 2, 3
6  4       4
7  3    4, 3
8  2 4, 3, 2
9  2 4, 3, 2
10 5       5
11 6    5, 6
12 7 5, 6, 7
13 9       9
14 8    9, 8

y$b是在每行中输出一个
列表
,如
list(1,2,3)
,或者只是一个粘贴的字符串,如
“1,2,3”
?嗨,作为字符串的输出是好的。如果有帮助,一个触发器可以指示我在注释中输入的点。谢谢。最近的邮件,太好了。我会深入了解你的魔法。一个疑问:unionlim接受两个变量x和y,如何在sapply中传递y?我只能看到通过a到x。。。谢谢。@Fabiocorea-
Reduce
是一个有趣的函数-它接受一个具有两个参数x/y的函数,但只有一个输入,因为它循环通过当前值加上循环的前一个输出-例如,递归地求和1到10,你可以
Reduce(函数(x,y)x+y,1:10,acculate=TRUE)
这就是
c(1,1+2=3,3+3=6,6+4=10,…
等。明白了,当然!谢谢。
bigy <- y[rep(1:nrow(y), 75e3)]
system.time({
  bigy[, out := sapply(Reduce(unionlim, a, accumulate=TRUE), paste, collapse=" ")]
})
#   user  system elapsed 
#  14.27    0.09   15.06 
y$b <- accumulate(y$a, ~if(length(union(.x, .y)) == 4) .y else union(.x, .y))

 y
   a       b
1  1       1
2  2    1, 2
3  2    1, 2
4  3 1, 2, 3
5  3 1, 2, 3
6  4       4
7  3    4, 3
8  2 4, 3, 2
9  2 4, 3, 2
10 5       5
11 6    5, 6
12 7 5, 6, 7
13 9       9
14 8    9, 8