You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

data.table内赋值lubridate的fast_strptime结果触发长度不匹配报错

问题复现

先构造测试用data.table对象:

library(data.table)
library(lubridate)

df <- data.table(a = c('2022-01-20', '2022-01-21'))
df

控制台输出:

a
1: 2022-01-20
2: 2022-01-21

直接对列向量调用fast_strptime()可以得到预期的日期时间结果:

fast_strptime(df$a, "%Y-%m-%d")

控制台输出:

[1] "2022-01-20 UTC" "2022-01-21 UTC"

但在data.table的:=更新语法中直接赋值会触发报错:

df[, a := fast_strptime(a, "%Y-%m-%d") ]

完整报错信息:

Error in `[.data.table`(df, , `:=`(a, fast_strptime(a, "%Y-%m-%d"))) : 
      Supplied 9 items to be assigned to 2 items of column 'a'. If you wish to 'recycle' the RHS please use rep() to make this intent clear to readers of your code.

报错字面含义为:目标列a只有2行,但赋值输入了9个元素,若需要循环填充请显式调用rep()说明意图。

报错根因

fast_strptime()默认返回POSIXlt类型对象,这类对象本质是长度为9的列表,9个元素分别对应秒、分、时、月内日期、月份、年份、周内日序、年内日序、夏令时标记字段,不是和行数等长的原子向量。
data.table执行:=赋值时会校验右侧输入的长度,直接传入POSIXlt对象会被判定为长度9的列表输入,和目标列2行的长度不匹配,因此抛出错误。单独在全局环境调用fast_strptime()时,控制台的打印方法会把POSIXlt列表渲染为熟悉的日期时间字符串,视觉上看起来是长度2的向量,很容易造成误判。

解决方法

两种方案都可以正常运行,按需选择即可:

  • 方案1:显式将fast_strptime返回的POSIXlt对象转换为data.table兼容的POSIXct原子向量类型:
df[, a := as.POSIXct(fast_strptime(a, "%Y-%m-%d"))]
  • 方案2:直接使用lubridate包中默认返回POSIXct类型的解析函数,无需手动做类型转换,代码更简洁。针对%Y-%m-%d格式的日期字符串,直接用ymd()即可自动识别解析:
df[, a := ymd(a)]

两种方式运行后都可以正确将字符列更新为日期时间类型,不会触发长度不匹配的报错。


内容的提问来源于stack exchange,提问作者Sweepy Dodo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 06:24:30