如何在 data.table 列中 label/count 连续的非 NA 值对?
How to label/count consecutive pairs of non-NA values in a data.table column?
我有以下 data.table,其中有一列 NA 值和字符类型的非 NA 值
library(data.table)
dt = fread(...)
print(dt$column1)
[1] NA NA NA "1 1" "1 1" "1 1" NA NA NA NA
[11] NA "1 2" NA NA NA NA NA NA NA NA
[21] NA NA NA NA NA NA NA NA NA NA
[31] NA NA NA NA NA "1 3" NA NA NA NA
[41] NA "1 4" "1 4" NA NA NA NA NA NA NA
[51] NA NA NA NA NA NA NA NA NA NA
[61] NA NA "1 5" NA NA NA NA NA NA NA
...
我想要一个新列来表示连续的非 NA 值的标签,即
print(dt$groups)
[1] 0 0 0 1 1 1 0 0 0 0
[11] 0 2 0 0 0 0 0 0 0 0
[21] 0 0 0 0 0 0 0 0 0 0
[31] 0 0 0 0 0 3 0 0 0 0
[41] 0 4 4 0 0 0 0 0 0 0
[51] 0 0 0 0 0 0 0 0 0 0
[61] 0 0 5 0 0 0 0 0 0 0
...
如果我试试这个:
dt[, groups := !is.na(column1)]
这将给我一个布尔向量,包含连续的 TRUE 语句。但是我不确定如何将其转换为连续对 TRUE 的标签。
有没有 data.table 方法来做到这一点?
这里是 rle
的解决方案:
library(data.table)
set.seed(1)
dt <- data.table(column1 = sample(c(rep(NA, 3), '1'), 30, replace = T))
x <- rle(dt$column1)
y <- cumsum(!is.na(x$values))
y[duplicated(y)] <- 0
x$values <- y
set(dt, NULL, 'group', inverse.rle(x))
# > dt
# column1 group
# 1: NA 0
# 2: NA 0
# 3: NA 0
# 4: 1 1
# 5: NA 0
# 6: 1 2
# 7: 1 2
# 8: NA 0
# 9: NA 0
# 10: NA 0
# 11: NA 0
# 12: NA 0
# 13: NA 0
# 14: NA 0
# 15: 1 3
# 16: NA 0
# 17: NA 0
# 18: 1 4
# 19: NA 0
# 20: 1 5
# 21: 1 5
# 22: NA 0
# 23: NA 0
# 24: NA 0
# 25: NA 0
# 26: NA 0
# 27: NA 0
# 28: NA 0
# 29: 1 6
# 30: NA 0
# column1 group
结合lmo的评论,可以简化为:
x <- rle(dt$column1)
x$values <- (!is.na(x$values)) * cumsum(!is.na(x$values))
set(dt, NULL, 'group', inverse.rle(x))
我有以下 data.table,其中有一列 NA 值和字符类型的非 NA 值
library(data.table)
dt = fread(...)
print(dt$column1)
[1] NA NA NA "1 1" "1 1" "1 1" NA NA NA NA
[11] NA "1 2" NA NA NA NA NA NA NA NA
[21] NA NA NA NA NA NA NA NA NA NA
[31] NA NA NA NA NA "1 3" NA NA NA NA
[41] NA "1 4" "1 4" NA NA NA NA NA NA NA
[51] NA NA NA NA NA NA NA NA NA NA
[61] NA NA "1 5" NA NA NA NA NA NA NA
...
我想要一个新列来表示连续的非 NA 值的标签,即
print(dt$groups)
[1] 0 0 0 1 1 1 0 0 0 0
[11] 0 2 0 0 0 0 0 0 0 0
[21] 0 0 0 0 0 0 0 0 0 0
[31] 0 0 0 0 0 3 0 0 0 0
[41] 0 4 4 0 0 0 0 0 0 0
[51] 0 0 0 0 0 0 0 0 0 0
[61] 0 0 5 0 0 0 0 0 0 0
...
如果我试试这个:
dt[, groups := !is.na(column1)]
这将给我一个布尔向量,包含连续的 TRUE 语句。但是我不确定如何将其转换为连续对 TRUE 的标签。
有没有 data.table 方法来做到这一点?
这里是 rle
的解决方案:
library(data.table)
set.seed(1)
dt <- data.table(column1 = sample(c(rep(NA, 3), '1'), 30, replace = T))
x <- rle(dt$column1)
y <- cumsum(!is.na(x$values))
y[duplicated(y)] <- 0
x$values <- y
set(dt, NULL, 'group', inverse.rle(x))
# > dt
# column1 group
# 1: NA 0
# 2: NA 0
# 3: NA 0
# 4: 1 1
# 5: NA 0
# 6: 1 2
# 7: 1 2
# 8: NA 0
# 9: NA 0
# 10: NA 0
# 11: NA 0
# 12: NA 0
# 13: NA 0
# 14: NA 0
# 15: 1 3
# 16: NA 0
# 17: NA 0
# 18: 1 4
# 19: NA 0
# 20: 1 5
# 21: 1 5
# 22: NA 0
# 23: NA 0
# 24: NA 0
# 25: NA 0
# 26: NA 0
# 27: NA 0
# 28: NA 0
# 29: 1 6
# 30: NA 0
# column1 group
结合lmo的评论,可以简化为:
x <- rle(dt$column1)
x$values <- (!is.na(x$values)) * cumsum(!is.na(x$values))
set(dt, NULL, 'group', inverse.rle(x))