使用带有NA的R data.table中的which.max时缺少值

时间:2018-04-30 17:38:55

标签: r data.table

我在进行分组时遇到了问题,并且在使用R data.table时遇到了which.max,我不确定它是否是一个错误,或者我不正确理解data.table中的分组结构。我有一个解决方法,我只是想了解为什么我的初始尝试失败了。

我正在查看包含时间序列的表格,我希望得到(a)感兴趣的事件发生的时间,或(b)时间序列中的最终时间戳。如果没有发生事件,则列标记事件为“NA”,如果没有,则为“1”。

以下是重现此问题的最小示例:

dt <- data.table(t = seq(9), event = c(NA, NA, NA, NA, 1, NA, 1, NA, NA), t_id = c(rep('A', 3), rep('B', 3), rep('C', 3)))
dt[, ifelse(is.null(which.max(event)), max(t), t[which.max(event)]), by=t_id]

返回

t_id    V1
   A    NA
   B    5
   C    7

组“A”的值是NA(我会天真地期望它是3)。如果我在没有ifelse函数的情况下运行它

dt[, t[which.max(event)], by=t_id]

“A”的行简直丢失(which.max返回NULL)。但如果我跑

dt[, is.null(which.max(event)), by=t_id]

我得到了

t_id    V1
   A    FALSE
   B    FALSE
   C    FALSE

我错过了什么?

1 个答案:

答案 0 :(得分:0)

这会有效吗?

library(data.table)
dt <- data.table(t = seq(9), 
                 event = c(NA, NA, NA, NA, 1, NA, 1, NA, NA), 
                 t_id = c(rep('A', 3), rep('B', 3), rep('C', 3)))
dt[, ifelse(length((na.omit(event)))==0, which.max(t), t[which.max(event)] ), by=t_id]


> dt[, ifelse(length((na.omit(event)))==0, which.max(t), t[which.max(event)] ), by=t_id]
   t_id V1
1:    A  3
2:    B  5
3:    C  7

你的方法的问题是which.max()不返回NULL对象:

> is.null(which.max(c(NA,NA,NA)))
[1] FALSE

但是如果你尝试length(),你会得到预期的结果:

> length(which.max(c(NA,NA,NA))) == 0
[1] TRUE

另外,我了解事件列可能包含1和NA以外的值。像:

dt <- data.table(t = seq(9), event = c(NA, NA, NA, NA, 1,3, 5, 2, NA, 2, 1, NA, NA), t_id = c(rep('A', 3), rep('B', 6), rep('C', 4)))
dt[, ifelse(length((na.omit(event)))==0, which.max(t), t[which.max(event)] ), by=t_id]

在这种情况下,数据表如下所示:

> dt
    t event t_id
 1: 1    NA    A
 2: 2    NA    A
 3: 3    NA    A
 4: 4    NA    B
 5: 5     1    B
 6: 6     3    B
 7: 7     5    B
 8: 8     2    B
 9: 9    NA    B
10: 1     2    C
11: 2     1    C
12: 3    NA    C
13: 4    NA    C

结果:

> dt[, ifelse(length((na.omit(event)))==0, which.max(t), t[which.max(event)] ), by=t_id]
   t_id V1
1:    A  3
2:    B  7
3:    C  1

如果事件列只能包含NAs1s,那么解决方案就会简单得多。

另一个注释(请参阅下面的讨论):对于这种情况,ifelse(na.omit())可能不是最有效的 - 可以在评论中找到一些建议。