R语言中如何将data.table内的NA日期值转换为指定日期?
解决data.table中日期列NA值替换为指定日期的问题
问题场景
你尝试将data.table日期列中的NA值替换为today()+360对应的日期,但使用ifelse后得到的是数字格式输出,而非预期的日期格式:
原代码:
library(data.table) library(lubridate) asdd <- data.frame(a = as.Date(c(NA, "1970-01-01")), b = c(2,3)) asdd <- as.data.table(asdd) asdd [,a := ifelse(is.na(a), as.Date(today()+360),a)]
得到的错误结果:
a b 1: 19580 2 2: 0 3
预期输出:
a b 1: 2023-08-11 2 2: 1970-01-01 3
问题原因
base::ifelse会自动简化返回值类型,Date类型本质是从1970-01-01开始计数的整数,因此ifelse会把Date对象转换为整数返回,导致列的Date类型丢失,最终显示为数字。
可行解决方案
以下三种方法均可实现预期效果:
方法1:直接使用data.table条件赋值(推荐)
利用data.table的行索引条件直接赋值,无需调用ifelse,完美保留Date类型:
library(data.table) library(lubridate) asdd <- data.frame(a = as.Date(c(NA, "1970-01-01")), b = c(2,3)) asdd <- as.data.table(asdd) # 仅对a列NA的行赋值 asdd[is.na(a), a := as.Date(today() + 360)] asdd
方法2:转换ifelse的输出为Date类型
如果一定要用ifelse,需将返回的整数重新转换为Date类型,指定原点为1970-01-01:
asdd[, a := as.Date(ifelse(is.na(a), today() + 360, as.integer(a)), origin = "1970-01-01")]
方法3:使用data.table的fifelse函数
data.table自带的fifelse会保留输入类型,不会像base::ifelse那样简化类型,用法和ifelse一致:
asdd[, a := fifelse(is.na(a), as.Date(today() + 360), a)]
内容的提问来源于stack exchange,提问作者manu p
相关产品推荐
相关产品推荐

