代码之家  ›  专栏  ›  技术社区  ›  LeGeniusII

不适用于带有data.table的日期

  •  1
  • LeGeniusII  · 技术社区  · 6 年前

    我有一个数据表

    require(data.table)
    require(lubridate)
    testDT <- data.table(dateA = c(NA,NA), dateB = c(ymd("20110101"),ymd("20100101")))
    testDT
    #       dateA      dateB
    #    1:    NA 2011-01-01
    #    2:    NA 2010-01-01
    

    我要执行以下操作:如果datea是na,则使用与dateb中相同的值。我试过以下命令:

    > testDT[is.na(dateA), dateA := dateB]
    Warning message:
    In `[.data.table`(testDT, is.na(dateA), `:=`(dateA, dateB)) :
      Coerced 'double' RHS to 'logical' to match the column's type; may have truncated precision. Either change the target column ['dateA'] to 'double' first (by creating a new 'double' vector length 2 (nrows of entire table) and assign that; i.e. 'replace' column), or coerce RHS to 'logical' (e.g. 1L, NA_[real|integer]_, as.*, etc) to make your intent clear and for speed. Or, set the column type correctly up front when you create the table and stick to it, please.
    

    如你所见,有一个警告,结果很奇怪:

    > testDT
       dateA      dateB
    1:  TRUE 2011-01-01
    2:  TRUE 2010-01-01
    

    为什么不起作用?

    我知道我们可以用:

    > testDT[,dateA := ifelse(is.na(dateA), dateB, dateA)]
    > testDT
       dateA      dateB
    1: 14975 2011-01-01
    2: 14610 2010-01-01
    > testDT[,dateA := as.Date(dateA, origin = "1970-01-01")]
    > testDT
            dateA      dateB
    1: 2011-01-01 2011-01-01
    2: 2010-01-01 2010-01-01
    
    2 回复  |  直到 6 年前
        1
  •  1
  •   Jaap    6 年前

    你收到警告信息是因为 dateA -列没有正确的类(如@emmanuel lin所述):

    > str(testDT)
    Classes ‘data.table’ and 'data.frame':    2 obs. of  2 variables:
     $ dateA: logi  NA NA
     $ dateB: Date, format: "2011-01-01" "2010-01-01"
     - attr(*, ".internal.selfref")=<externalptr>
    

    一个可能的解决方案是转换 日期 -列到日期类的第一个 as.Date 或者内置日期函数 以下内容:

    # convert 'dateA'-column to 'Date'- class first
    testDT[, dateA := as.Date(dateA)]   # alternatively: as.IDate(dateA)
    
    # fill the 'NA' values in the 'dateA'-column
    testDT[is.na(dateA), dateA := dateB][]
    

    它给出:

    > testDT
            dateA      dateB
    1: 2011-01-01 2011-01-01
    2: 2010-01-01 2010-01-01
    
        2
  •  0
  •   Emmanuel-Lin    6 年前

    因为在第一列中只有NAS,所以它猜测这是合乎逻辑的。

    如果您添加了一个不是na的元素,那么它工作得很好:

    你的例子还有一个元素

    require(data.table)
    require(lubridate)
    testDT <- data.table(dateA = c(NA,NA, ymd("20110101")), dateB = c(ymd("20110101"),ymd("20100101"), ymd("20100101")))
    
    testDT[is.na(dateA), dateA := dateB]
    

    结果是:

    > testDT
       dateA      dateB
    1: 14975 2011-01-01
    2: 14610 2010-01-01
    3: 14975 2010-01-01
    

    那你为什么只有NAS?