我已经开始了一个新项目,其中包含一系列我以前从未做过的数据管理,而且我似乎缺乏技能或适当的搜索条件来查找示例。我有一个非常大的数据集,其中包含分组变量和二进制事件变量。它可以推广到一个工作示例:
library('data.table')
grp <- c("a", "a", "a", "a", "a", "a", "a", "b", "b", "b", "b", "b")
v1 <- c(1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1)
test<-data.frame(grp,v1)
test
grp v1
1 a 1
2 a 0
3 a 0
4 a 1
5 a 1
6 a 1
7 a 1
8 b 1
9 b 0
10 b 0
11 b 0
12 b 1
我一直在使用data.table
在“grp”的唯一级别中将“v1”的条纹标记为具有新的序数数字因子“event”的事件:
setDT(test)
test<-test[, .(v1 = v1, event = rleidv(v1)), by=grp]
grp v1 event
1: a 1 1
2: a 0 2
3: a 0 2
4: a 1 3
5: a 1 3
6: a 1 3
7: a 1 3
8: b 1 1
9: b 0 2
10: b 0 2
11: b 0 2
12: b 1 3
在实际数据集中,这些“grp”特定事件中的一些非常长,我需要将它们分解为较小的,可变的, n - 有限的事件。例如,我对 n = 2的新变量“sub.event”的所需输出是:
> test
grp v1 event sub.event
1: a 1 1 1
2: a 0 2 2
3: a 0 2 2
4: a 1 3 3
5: a 1 3 3
6: a 1 3 4
7: a 1 3 4
8: b 1 1 1
9: b 0 2 2
10: b 0 2 2
11: b 0 2 3
12: b 1 3 4
我一直在拉着我的头发试图找到一种方法来做到这一点。看起来很简单,我必须遗漏一些明显的东西。为了方便起见,在确定 n -limited“sub.event”之前,可以将原始变量连接成新变量。
提前感谢您的帮助。
答案 0 :(得分:3)
这是一种适用于链接的方法。
setDT(test)[, new := rep(1:0, length.out=.N), by=.(grp, rleid(v1))][,
new := cumsum(new), by=grp]
第一个链返回1s和0s的向量,重复grp - rleid
对的长度。链中的下一个链接通过grp。{/ p>与cumsum
进行求和
返回
test
grp v1 new
1: a 1 1
2: a 0 2
3: a 0 2
4: a 1 3
5: a 1 3
6: a 1 4
7: a 1 4
8: b 1 1
9: b 0 2
10: b 0 2
11: b 0 3
12: b 1 4
请注意,如上所述,它不会自动扩展到n&gt; 2.但是,产生它的作品1:0
可以写成rep(c(1L, rep(0L, n)), length.out=.N)
,其中n+1
是您想要的重复值的数量。
在这种情况下,代码看起来像
test[, new := rep(c(1L, rep(0L, 2L)), length.out=.N), by=.(grp, rleid(v1))][,
new := cumsum(new), by=grp]
答案 1 :(得分:2)
有点迂回:
# make counters within v1, grp
test[, v0 := rep(1:.N, each=2, length.out=.N), by=.(rleid(grp, v1))]
# make overall counters
test[, v := .GRP, by=rleid(grp, v1, v0)]
# difference per grp
test[, v := v - first(v) + 1L, by=grp]
# drop internal counter
test[, v0 := NULL ]
grp v1 v
1: a 1 1
2: a 0 2
3: a 0 2
4: a 1 3
5: a 1 3
6: a 1 4
7: a 1 4
8: b 1 1
9: b 0 2
10: b 0 2
11: b 0 3
12: b 1 4