【问题标题】:Convert multiple date column of a data.table转换data.table的多个日期列
【发布时间】:2020-11-15 21:15:23
【问题描述】:

我正在尝试在data.table 中转换多个日期列(具有不同的格式)。目前可用的方法很少。链接Efficiently convert a date column in data.table 之一。我正在尝试使用mapply。但出现以下错误:

[.data.table(df, , :=((paste0(dtVar, "")) 中的错误, mapply(function(x, : 提供 12 项分配给 6 项 列'X1'。如果您想“回收”RHS,请使用 rep() 来 让代码的读者清楚这一意图。

library(data.table)

# sample data
df <- data.table(
  X1 = c("1996-01-04", "1996-01-05", "1996-01-08", "1996-01-09", "1996-01-10", "1996-01-11"), 
  X2 = c("02/01/1996", "03/01/1996", "04/01/1996", "05/01/1996", "08/01/1996", "09/01/1996"), 
  stringsAsFactors = FALSE)


# convert date columns
dtVar <- c("X1", "X2")
inDtFmt <- c("%Y-%m-%d","%d/%m/%Y")

df[,(dtVar) := mapply(function(x,y){strptime(df[[x]], format = y)}, dtVar, inDtFmt)]

## Further investigation
mm <- mapply(function(x,y){strptime(df[[x]], format = y)}, dtVar, inDtFmt)

str(mm)
List of 2
# $ X1: POSIXlt[1:6], format: "1996-01-04" "1996-01-05" "1996-01-08" "1996-01-09" ...
# $ X2: POSIXlt[1:6], format: "1996-01-02" "1996-01-03" "1996-01-04" "1996-01-05" ...

谁能告诉我为什么会出现这个错误?

【问题讨论】:

    标签: r date data.table


    【解决方案1】:

    我们可以使用anydate from anytime,它可以自动选择格式并更改为Date

    library(data.table)
    library(anytime)
    df[, (dtVar) := lapply(.SD, anydate), .SDcols = dtVar]
    
    str(df)
    #Classes ‘data.table’ and 'data.frame': 6 obs. of  2 variables:
    # $ X1: Date, format: "1996-01-04" "1996-01-05" "1996-01-08" "1996-01-09" ...
    # $ X2: Date, format: "1996-02-01" "1996-03-01" "1996-04-01" "1996-05-01" ...
    

    【讨论】:

      【解决方案2】:

      这是一种方法:

      
      library(data.table)
      
      # sample data
      df <- data.table(
        X1 = c("1996-01-04", "1996-01-05", "1996-01-08", "1996-01-09", "1996-01-10", "1996-01-11"), 
        X2 = c("02/01/1996", "03/01/1996", "04/01/1996", "05/01/1996", "08/01/1996", "09/01/1996"), 
        stringsAsFactors = FALSE)
      
      str(df)
      
      dtFmt <- list(X1 = "%Y-%m-%d", X2 = "%d/%m/%Y")
      
      for (col in names(df)) {
        df[[col]] <- as.Date(df[[col]],  dtFmt[[col]]) 
      }
      
      str(df)
      
      

      【讨论】:

      • 欢迎来到 Stack Overflow。请不要发布仅代码的答案,您应该解释此代码的工作原理并回答问题。这使得它对 OP 以及其他有类似问题的用户更有用,因此更有可能被点赞。
      【解决方案3】:

      mapply 通常会尝试将结果简化为向量,您应该改用Mapstrptime 返回类 POSIXlt 的对象,这里你只需要日期所以使用 as.Date

      此外,如果您使用lubridate::parse_date_time,您可以使用lapply 执行此操作。

      library(data.table)
      
      df[, (dtVar) := lapply(.SD, lubridate::parse_date_time, inDtFmt), .SDcols = dtVar]
      df
      
      #           X1         X2
      #1: 1996-01-04 1996-01-02
      #2: 1996-01-05 1996-01-03
      #3: 1996-01-08 1996-01-04
      #4: 1996-01-09 1996-01-05
      #5: 1996-01-10 1996-01-08
      #6: 1996-01-11 1996-01-09
      

      【讨论】:

      • 是的..你是对的..在mapply中使用SIMPLIFY = F时没有错误..
      【解决方案4】:

      你可以使用as.IDate:

      df <- df[,as.list(Map(function(x,y){as.IDate(.SD[[x]], format = y)}, dtVar, inDtFmt))]
      print(df)
      
                 X1         X2
      1: 1996-01-04 1996-01-02
      2: 1996-01-05 1996-01-03
      3: 1996-01-08 1996-01-04
      4: 1996-01-09 1996-01-05
      5: 1996-01-10 1996-01-08
      6: 1996-01-11 1996-01-09
      

      【讨论】:

        猜你喜欢
        • 2018-02-15
        • 1970-01-01
        • 2020-01-08
        • 2022-06-28
        • 2013-09-02
        • 2020-05-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多