我有一个数据表,格式如下(2000000+行,1000+组):
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"。所以条件是:如果在 "b" 之前出现字符 "a" 或一系列字符 "a",替换所有字符 "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解决方案。
dt[values != "a" , v2 := values]
;dt[, v2 := zoo::na.locf(v2, fromLast = TRUE, na.rm = FALSE), by = "id"]
;dt[values == "a" & v2 == "b", values := v2]
- Djpengona.locf
,但它的速度要慢得多,所以我决定将其排除在外(抱歉,我应该在帖子中提到这一点)。我可能会重新加入它。 - Henrik