【问题标题】:dates: Not yet implemented NAbounds=TRUE for this non-numeric and non-character type日期:尚未针对此非数字和非字符类型实现 NAbounds=TRUE
【发布时间】:2021-11-29 17:26:55
【问题描述】:

我有这个数据框:

df1 <- structure(list(ID = c(1, 2, 2, 2, 3, 4, 5, 6, 6, 7, 8, 8, 9, 
10), dateA = structure(c(14974, 18628, 18628, 18628, 14882, 16800, 
14882, 17835, 17835, 16832, 16556, 16556, 15949, 16801), class = "Date"), 
dateB = structure(c(14610, 15340, 15706, 17501, 14730, NA, 
14700, 16191, 17106, 16801, 15810, 16436, 14655, 15431), class = "Date"), 
dateC = structure(c(18628, 15705, 17500, 18628, 18628, NA, 
18628, 17105, 18628, 18628, 16435, 16556, 15706, 18628), class = "Date")), row.names = c(NA, 
-14L), class = c("data.table", "data.frame"))

    ID      dateA      dateB      dateC
 1:  1 2010-12-31 2010-01-01 2021-01-01
 2:  2 2021-01-01 2012-01-01 2012-12-31
 3:  2 2021-01-01 2013-01-01 2017-11-30
 4:  2 2021-01-01 2017-12-01 2021-01-01
 5:  3 2010-09-30 2010-05-01 2021-01-01
 6:  4 2015-12-31       <NA>       <NA>
 7:  5 2010-09-30 2010-04-01 2021-01-01
 8:  6 2018-10-31 2014-05-01 2016-10-31
 9:  6 2018-10-31 2016-11-01 2021-01-01
10:  7 2016-02-01 2016-01-01 2021-01-01
11:  8 2015-05-01 2013-04-15 2014-12-31
12:  8 2015-05-01 2015-01-01 2015-05-01
13:  9 2013-09-01 2010-02-15 2013-01-01
14: 10 2016-01-01 2012-04-01 2021-01-01

我想检查 dateA 是否在 dateB 和 dateC 的区间内: 我的代码:

library(dplyr)
df1 %>% 
  mutate(match= ifelse(between(dateA, dateB, dateC), 1, 0))

给予:

Error: Problem with `mutate()` column `match`.
i `match = ifelse(between(dateA, dateB, dateC), 1, 0)`.
x Not yet implemented NAbounds=TRUE for this non-numeric and non-character type

如果我删除包含 NA 的行,则代码有效:

df1 %>% 
  slice(-6) %>% 
  mutate(match= ifelse(between(dateA, dateB, dateC), 1, 0))

我想知道,我可以离开NA 所在的行并执行我的代码吗?

【问题讨论】:

    标签: r dplyr na


    【解决方案1】:

    对于 OP 使用的是哪个 between 存在混淆,因为输入对象是 data.table 并且使用的代码是 dplyr。因此,如果我们假设两个包都已加载,那么每个包中都有一个 between 函数,并且根据最后加载的包,前一个包中的 between 将被屏蔽。如果使用dplyr::between,它没有完全矢量化,它记录在?dplyr::between

    left、right 边界值(必须是标量)。

    df1 %>%
        rowwise %>% 
        mutate(match = +(dplyr::between(dateA, dateB, dateC))) %>%
        ungroup
    

    -输出

    # A tibble: 14 × 5
          ID dateA      dateB      dateC      match
       <dbl> <date>     <date>     <date>     <int>
     1     1 2010-12-31 2010-01-01 2021-01-01     1
     2     2 2021-01-01 2012-01-01 2012-12-31     0
     3     2 2021-01-01 2013-01-01 2017-11-30     0
     4     2 2021-01-01 2017-12-01 2021-01-01     1
     5     3 2010-09-30 2010-05-01 2021-01-01     1
     6     4 2015-12-31 NA         NA            NA
     7     5 2010-09-30 2010-04-01 2021-01-01     1
     8     6 2018-10-31 2014-05-01 2016-10-31     0
     9     6 2018-10-31 2016-11-01 2021-01-01     1
    10     7 2016-02-01 2016-01-01 2021-01-01     1
    11     8 2015-05-01 2013-04-15 2014-12-31     0
    12     8 2015-05-01 2015-01-01 2015-05-01     1
    13     9 2013-09-01 2010-02-15 2013-01-01     0
    14    10 2016-01-01 2012-04-01 2021-01-01     1
    

    但是,?data.table::between 并非如此(根据 OP 帖子中显示的错误,使用的 between 似乎来自 data.table

    lower - 下限。长度为 1 或与 x 相同。

    upper - 范围上限。长度为 1 或与 x 相同。

    class 可能是个问题,尽管它另有说明

    x- 任意可排序向量,即具有&lt;=相关方法的向量,如介于之间的数字、字符、日期等,以及范围内的数字向量。

    Date 类转换为integer/numeric,它应该可以工作

    df1 %>%
       mutate(match = +(data.table::between(as.numeric(dateA), 
           as.numeric(dateB), as.numeric(dateC))))
    

    -输出

    ID      dateA      dateB      dateC match
     1:  1 2010-12-31 2010-01-01 2021-01-01     1
     2:  2 2021-01-01 2012-01-01 2012-12-31     0
     3:  2 2021-01-01 2013-01-01 2017-11-30     0
     4:  2 2021-01-01 2017-12-01 2021-01-01     1
     5:  3 2010-09-30 2010-05-01 2021-01-01     1
     6:  4 2015-12-31       <NA>       <NA>     1
     7:  5 2010-09-30 2010-04-01 2021-01-01     1
     8:  6 2018-10-31 2014-05-01 2016-10-31     0
     9:  6 2018-10-31 2016-11-01 2021-01-01     1
    10:  7 2016-02-01 2016-01-01 2021-01-01     1
    11:  8 2015-05-01 2013-04-15 2014-12-31     0
    12:  8 2015-05-01 2015-01-01 2015-05-01     1
    13:  9 2013-09-01 2010-02-15 2013-01-01     0
    14: 10 2016-01-01 2012-04-01 2021-01-01     1
    

    通过深入研究,问题在于参数NAbounds,默认情况下为TRUE。在 OP 的数据中,有一个 NA 元素

    df1 %>% 
        mutate(match = data.table::between(dateA, dateB, dateC))
    

    错误:mutate()match 有问题。 ℹmatch = data.table::between(dateA, dateB, dateC)。 ✖ 对于这种非数字和非字符类型,尚未实现 NAbounds=TRUE 运行rlang::last_error() 看看哪里出错了。

    我们可能需要将此设置为FALSE

    df1 %>% 
       mutate(match = +(data.table::between(dateA, dateB, dateC, NAbounds = FALSE)))
        ID      dateA      dateB      dateC match
     1:  1 2010-12-31 2010-01-01 2021-01-01     1
     2:  2 2021-01-01 2012-01-01 2012-12-31     0
     3:  2 2021-01-01 2013-01-01 2017-11-30     0
     4:  2 2021-01-01 2017-12-01 2021-01-01     1
     5:  3 2010-09-30 2010-05-01 2021-01-01     1
     6:  4 2015-12-31       <NA>       <NA>    NA
     7:  5 2010-09-30 2010-04-01 2021-01-01     1
     8:  6 2018-10-31 2014-05-01 2016-10-31     0
     9:  6 2018-10-31 2016-11-01 2021-01-01     1
    10:  7 2016-02-01 2016-01-01 2021-01-01     1
    11:  8 2015-05-01 2013-04-15 2014-12-31     0
    12:  8 2015-05-01 2015-01-01 2015-05-01     1
    13:  9 2013-09-01 2010-02-15 2013-01-01     0
    14: 10 2016-01-01 2012-04-01 2021-01-01     1
    

    或者也可以使用as.DateNA 进行转换

    df1 %>% 
        mutate(match = +(data.table::between(dateA, dateB, dateC, 
             NAbounds = as.Date(NA))))
        ID      dateA      dateB      dateC match
     1:  1 2010-12-31 2010-01-01 2021-01-01     1
     2:  2 2021-01-01 2012-01-01 2012-12-31     0
     3:  2 2021-01-01 2013-01-01 2017-11-30     0
     4:  2 2021-01-01 2017-12-01 2021-01-01     1
     5:  3 2010-09-30 2010-05-01 2021-01-01     1
     6:  4 2015-12-31       <NA>       <NA>    NA
     7:  5 2010-09-30 2010-04-01 2021-01-01     1
     8:  6 2018-10-31 2014-05-01 2016-10-31     0
     9:  6 2018-10-31 2016-11-01 2021-01-01     1
    10:  7 2016-02-01 2016-01-01 2021-01-01     1
    11:  8 2015-05-01 2013-04-15 2014-12-31     0
    12:  8 2015-05-01 2015-01-01 2015-05-01     1
    13:  9 2013-09-01 2010-02-15 2013-01-01     0
    14: 10 2016-01-01 2012-04-01 2021-01-01     1
    

    【讨论】:

    • 仍然给出:error: Problem with mutate() column match. i match = +(between(dateA, dateB, dateC)). x Not yet implemented NAbounds=TRUE for this non-numeric and non-character type i The error occurred in row 6.
    • 谢谢你的提示:这工作df1 %&gt;% rowwise %&gt;% mutate(match = +(dplyr::between(dateA, dateB, dateC)))
    • @TarJae 这是因为您正在使用的between 存在冲突。也许在您的情况下,您使用的是data.table::between 而不是dplyr::between,但由于类问题,它会给出错误。请检查我的更新
    • @TarJae 您在逻辑输出上使用 ifelse 将 TRUE 转换为 1 并将 FALSE 转换为 0。而是直接使用 as.integer+ 将 TRUE/FALSE 强制转换为其存储值 1 /0
    • @TarJae 我想我理解这个问题。请检查更新
    【解决方案2】:
    library(tidyverse)
    library(lubridate)
    
    
    df1 %>% 
      mutate(res = +(dateA %within% interval(dateB, dateC)))
    #>    ID      dateA      dateB      dateC res
    #> 1   1 2010-12-31 2010-01-01 2021-01-01   1
    #> 2   2 2021-01-01 2012-01-01 2012-12-31   0
    #> 3   2 2021-01-01 2013-01-01 2017-11-30   0
    #> 4   2 2021-01-01 2017-12-01 2021-01-01   1
    #> 5   3 2010-09-30 2010-05-01 2021-01-01   1
    #> 6   4 2015-12-31       <NA>       <NA>  NA
    #> 7   5 2010-09-30 2010-04-01 2021-01-01   1
    #> 8   6 2018-10-31 2014-05-01 2016-10-31   0
    #> 9   6 2018-10-31 2016-11-01 2021-01-01   1
    #> 10  7 2016-02-01 2016-01-01 2021-01-01   1
    #> 11  8 2015-05-01 2013-04-15 2014-12-31   0
    #> 12  8 2015-05-01 2015-01-01 2015-05-01   1
    #> 13  9 2013-09-01 2010-02-15 2013-01-01   0
    #> 14 10 2016-01-01 2012-04-01 2021-01-01   1
    

    数据

    df1 <- structure(
      list(
        ID = c(1, 2, 2, 2, 3, 4, 5, 6, 6, 7, 8, 8, 9,
               10),
        dateA = structure(
          c(
            14974,
            18628,
            18628,
            18628,
            14882,
            16800,
            14882,
            17835,
            17835,
            16832,
            16556,
            16556,
            15949,
            16801
          ),
          class = "Date"
        ),
        dateB = structure(
          c(
            14610,
            15340,
            15706,
            17501,
            14730,
            NA,
            14700,
            16191,
            17106,
            16801,
            15810,
            16436,
            14655,
            15431
          ),
          class = "Date"
        ),
        dateC = structure(
          c(
            18628,
            15705,
            17500,
            18628,
            18628,
            NA,
            18628,
            17105,
            18628,
            18628,
            16435,
            16556,
            15706,
            18628
          ),
          class = "Date"
        )
      ),
      row.names = c(NA,-14L),
      class = c("data.table", "data.frame")
    )
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-16
      • 2021-06-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多