根据前面的值按组替换值序列 [英] Replace a sequence of values by group depending on preceeding values
本文介绍了根据前面的值按组替换值序列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我有一个此表单的数据表(2000000+行,1,000+组):
set.seed(1)
dt <- data.table(id = rep(1:3, each = 5), values = sample(c("a", "b","c"), 15, TRUE))
> dt
id values
1: 1 a
2: 1 c
3: 1 a
4: 1 b
5: 1 a
6: 2 c
7: 2 c
8: 2 b
9: 2 b
10: 2 c
11: 3 c
12: 3 a
13: 3 a
14: 3 a
15: 3 b
在每个ID组中,我希望替换字符"b"之前的整个字符"a"序列,并希望将它们替换为"b"。因此,条件是如果"a"或一系列的"a"出现在"b"之前,替换所有的"a"。(实际上,在我的实际表格中,当"b"前面是"a"、"x"或"y"时,应该替换前面的字符,但我应该能够泛化)
在上面的示例中,应该替换第3行中的"a"值(很容易使用data.table中的(Shift)),以及第12-14行中的所有"a"(不确定该怎么做)。因此,期望的输出如下所示:
> dt
id values
1: 1 a
2: 1 c
3: 1 b
4: 1 b
5: 1 a
6: 2 c
7: 2 c
8: 2 b
9: 2 b
10: 2 c
11: 3 c
12: 3 b
13: 3 b
14: 3 b
15: 3 b
我脑海中浮现的是从最后一个索引开始循环,但是如果我有多个分组(比如ID和DATE),我不太确定该怎么做,而且无论如何,这似乎不是最快的DT解决方案。
推荐答案
您可以使用rle()
。
注意:为避免歧义,我将"values"
列重命名为"var"
,因为rle()
函数还会生成一个包含名为"values"
的向量的列表。
dt[, new := with(rle(var), rep(ifelse(values == "a" & c(values[-1], "") == "b", "b", values), lengths)), by = id]
dt
# id var new
# 1: 1 a a
# 2: 1 c c
# 3: 1 a b
# 4: 1 b b
# 5: 1 a a
# 6: 2 c c
# 7: 2 c c
# 8: 2 b b
# 9: 2 b b
# 10: 2 c c
# 11: 3 c c
# 12: 3 a b
# 13: 3 a b
# 14: 3 a b
# 15: 3 b b
这篇关于根据前面的值按组替换值序列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文