【问题标题】:How to label/count consecutive pairs of non-NA values in a data.table column?如何在 data.table 列中标记/计算连续的非 NA 值对?
【发布时间】:2017-05-08 16:46:48
【问题描述】:

我有以下 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 方法可以做到这一点?

【问题讨论】:

  • dt[, groups := !is.na(column1) * cumsum(!is.na(column1))] 可能会起作用,但是如果没有working example 就很难测试代码。
  • @lmo,不错的尝试。但这将为前 3 个连续的非 NA 值分配不同的组 ID。你错过了一对括号:(!is.na(column1)) * cumsum(!is.na(column1))
  • @mt1022 谢谢。就像我说的,没有工作示例就很难测试代码。

标签: r boolean label data.table na


【解决方案1】:

这是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))

【讨论】:

  • 感谢您的帮助。不过,我没有关注您的变量名:第一个代码 sn-p 中的x$values 是什么?我收到错误Error in x$values : $ operator is invalid for atomic vectors
  • @ShanZhengYang, x &lt;- rle(dt$column1) 将创建一个带有rle 类的列表。它有两个元素:lengthsvalues
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-01
  • 2019-03-01
  • 2022-11-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多