【问题标题】:aggregating class Date columns in data.table returns non-empty NAs. R聚合 data.table 中的类 Date 列返回非空 NA。 R
【发布时间】:2019-09-30 00:21:31
【问题描述】:

我有一个带有几个 Date 列的 data.table dt。当我聚合表时,我得到一些条目的 NA 值。这是意料之中的。但是,该字段实际上不是 NA,即使它显示它是 NA。当我比较那些 NA 日期字段时,我没有得到预期的 NA。这是一个我不理解的奇怪结果,它对我的​​分析造成了严重破坏。

> dt <- data.table(cust = c(1,1,2,2,2,3,3)
                 , DTE_off = as.Date(c('2018-07-31', '2019-05-06', '2014-06-01', '2015-06-01', '2019-05-06', '2018-06-18', '2019-05-06'), '%Y-%m-%d')
                 , chp_start = as.Date(c('2001-01-22', '2001-01-22', '2000-01-01', '2000-01-01', '2000-01-01', '2000-01-01', '2000-01-01'), '%Y-%m-%d')
                 , chp_end = as.Date(c('2019-05-05', '2019-05-05', '2019-05-05', '2019-05-05', '2019-05-05', '2019-05-05', '2019-05-05'), '%Y-%m-%d')
                 , prod_any = c('Y','Y','Y','Y', 'Y','N','N')) 

> dt
   cust    DTE_off  chp_start    chp_end prod_any
1:    1 2018-07-31 2001-01-22 2019-05-05        Y
2:    1 2019-05-06 2001-01-22 2019-05-05        Y
3:    2 2014-06-01 2000-01-01 2019-05-05        Y
4:    2 2015-06-01 2000-01-01 2019-05-05        Y
5:    2 2019-05-06 2000-01-01 2019-05-05        Y
6:    3 2018-06-18 2000-01-01 2019-05-05        N
7:    3 2019-05-06 2000-01-01 2019-05-05        N
> dt[, month := format(DTE_off, '%Y-%m')]
> dt
   cust    DTE_off  chp_start    chp_end prod_any   month
1:    1 2018-07-31 2001-01-22 2019-05-05        Y 2018-07
2:    1 2019-05-06 2001-01-22 2019-05-05        Y 2019-05
3:    2 2014-06-01 2000-01-01 2019-05-05        Y 2014-06
4:    2 2015-06-01 2000-01-01 2019-05-05        Y 2015-06
5:    2 2019-05-06 2000-01-01 2019-05-05        Y 2019-05
6:    3 2018-06-18 2000-01-01 2019-05-05        N 2018-06
7:    3 2019-05-06 2000-01-01 2019-05-05        N 2019-05
> dt_agg <- dt[ ,.(last_dte_off = max(DTE_off), any_start = max(chp_start[which(prod_any == "Y")], na.rm = TRUE), any_end = max(chp_end[which(prod_any == "Y")], na.rm = TRUE)) , by = .(cust, month)]
Warning messages:
1: In max.default(numeric(0), na.rm = TRUE) :
  no non-missing arguments to max; returning -Inf
2: In max.default(numeric(0), na.rm = TRUE) :
  no non-missing arguments to max; returning -Inf
3: In max.default(numeric(0), na.rm = TRUE) :
  no non-missing arguments to max; returning -Inf
4: In max.default(numeric(0), na.rm = TRUE) :
  no non-missing arguments to max; returning -Inf

当我在 dt_agg 中检查 NA 时,没有。但是当我查看数据时,有NA。这些 NA 是有效的(它们应该在那里!)

> anyNA(dt_agg)
[1] FALSE
> dt_agg
   cust   month last_dte_off  any_start    any_end
1:    1 2018-07   2018-07-31 2001-01-22 2019-05-05
2:    1 2019-05   2019-05-06 2001-01-22 2019-05-05
3:    2 2014-06   2014-06-01 2000-01-01 2019-05-05
4:    2 2015-06   2015-06-01 2000-01-01 2019-05-05
5:    2 2019-05   2019-05-06 2000-01-01 2019-05-05
6:    3 2018-06   2018-06-18       <NA>       <NA>
7:    3 2019-05   2019-05-06       <NA>       <NA>

更糟糕的是,当我尝试比较 dt_agg 中的聚合日期字段时,具有 NA 的条目应该返回 NA,但它们实际上返回一个值。这意味着从技术上讲,它们不是 NA。我不确定发生了什么。

> dt_agg[, compare := any_start > any_end]
> dt_agg
   cust   month last_dte_off  any_start    any_end compare
1:    1 2018-07   2018-07-31 2001-01-22 2019-05-05   FALSE
2:    1 2019-05   2019-05-06 2001-01-22 2019-05-05   FALSE
3:    2 2014-06   2014-06-01 2000-01-01 2019-05-05   FALSE
4:    2 2015-06   2015-06-01 2000-01-01 2019-05-05   FALSE
5:    2 2019-05   2019-05-06 2000-01-01 2019-05-05   FALSE
6:    3 2018-06   2018-06-18       <NA>       <NA>   FALSE  # what's going on here?!? compare should be NA, not FALSE
7:    3 2019-05   2019-05-06       <NA>       <NA>   FALSE  # what's going on here?! compare should be NA, NOT FALSE

我认为这总体上与 Date 类有关。但是,看到不是 NA 的 NA 值还是有点荒谬?

【问题讨论】:

  • 当特定组合没有“Y”时会出现问题 (cust = 3) 您想如何处理这些情况
  • 如果您想为这些情况返回 NA dt[, .(last_dte_off = max(DTE_off), any_start = if(!any(prod_any == "Y")) NA_real_ else max(chp_start[which(prod_any == "Y")], na.rm = TRUE)), by = .(cust, month)]

标签: r date data.table aggregate na


【解决方案1】:

警告与数据中的NAs 无关,但特定组的“prod_any”值不为“Y”,当我们将which 包装在这些上时,它会给出类似于

which(c(1, 3) == 5)
#integer(0)

和其中的max 发出警告

max(which(c(1, 3) == 5), na.rm = TRUE)
#[1] -Inf

警告消息:在 max(which(c(1, 3) == 5), na.rm = TRUE) 中:否 max 的非缺失参数;返回 -Inf


为避免警告,我们可以通过使用 `if/else 条件包装来跳过这些组上的 max

dt[, .(last_dte_off = max(DTE_off),
        any_start = if(!any(prod_any == "Y")) NA_real_ # changed here
              else max(chp_start[which(prod_any == "Y")], na.rm = TRUE),
         any_end = if(!any(prod_any == "Y")) NA_real_  
              else max(chp_end[which(prod_any == "Y")], na.rm = TRUE)),
         by = .(cust, month)]
#   cust   month last_dte_off  any_start    any_end
#1:    1 2018-07   2018-07-31 2001-01-22 2019-05-05
#2:    1 2019-05   2019-05-06 2001-01-22 2019-05-05
#3:    2 2014-06   2014-06-01 2000-01-01 2019-05-05
#4:    2 2015-06   2015-06-01 2000-01-01 2019-05-05
#5:    2 2019-05   2019-05-06 2000-01-01 2019-05-05
#6:    3 2018-06   2018-06-18       <NA>       <NA>
#7:    3 2019-05   2019-05-06       <NA>       <NA>

这里没有警告

【讨论】:

  • 感谢@akrun。这解决了我的问题。 “不真实”的 NA 非常令人困惑。为什么它甚至存在?! (也许是反问)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-03-10
  • 2013-06-15
  • 1970-01-01
  • 2021-07-18
  • 2016-03-24
  • 2015-07-04
  • 1970-01-01
相关资源
最近更新 更多