Djp*_*ngo 10 string replace r sequence data.table
我有一个这种形式的数据表(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
Run Code Online (Sandbox Code Playgroud)
我想在每个 ID 组中替换字符“b”之前的整个字符“a”序列,并且我想用“b”替换它们。所以条件是,如果 "a" 或一系列 "a" 出现在 "b" 之前,则替换所有的 "a"。(实际上,在我的真实表格中,当“b”前面是“a”、“x”或“y”时,应该替换前面的字符,但我应该能够概括)
在上面的例子中,第 3 行中“a”的值应该被替换(很容易在 data.table 中使用(移位)),以及第 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
Run Code Online (Sandbox Code Playgroud)
我想到的是从最后一个索引开始循环,但是如果我有多个分组(比如 ID 和 DATE),我不确定如何做到这一点,无论如何,这似乎不是最快的 dt 解决方案.
这是另一种 data.table 方法:
dt[, x := rleid(values), by = .(id)]
dt[dt[values == "b", .(id, x=x-1, values="a")],
on = .(id, x, values),
values := "b"
][, x := NULL]
Run Code Online (Sandbox Code Playgroud)
结果是:
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
Run Code Online (Sandbox Code Playgroud)
以下是您要将值“a”、“x”或“y”后跟“b”替换为“b”的情况的概括:
dt[, x := rleid(values), by = .(id)]
dt[dt[values == "b", .(values=c("a", "x", "y")), by = .(id, x=x-1)],
on = .(id, x, values),
values := "b"
][, x := NULL]
Run Code Online (Sandbox Code Playgroud)
您可以使用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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
249 次 |
| 最近记录: |