如何将R数据框中的日、月、年三列合并为日期列?
解决R语言中合并day/month/year列为日期列的问题
咱们来逐个分析你遇到的问题,再给出简单好用的解决方案:
第一个代码的问题
你用的这段base R代码:
as.Date(paste(dt$mon,dt$day,dt$year,sep="-"),format = "%m-%d-%y")
得到异常日期(比如2020-10-10而不是2017-10-10)的核心原因是年份格式符用错了:
%y是用来解析两位年份的(比如"17"对应2017),但你的year列是四位数字(2017、2018),用%y解析四位年份会导致识别错误,把"2017"的前两位当成年份,最终得到错误的2020年。- 正确的格式符应该是
%Y,专门对应四位年份。
修正后的代码应该是:
dt$date <- as.Date(paste(dt$mon, dt$day, dt$year, sep = "-"), format = "%m-%d-%Y")
这样就能正确解析出2017-10-10和2018-04-04,NA值也会被正常保留。
第二个lubridate代码的问题
你尝试的这段代码:
library("lubridate") with(dt, ymd(sprintf('%04d%02d%02d', year, mon, day)))
报错的原因是sprintf的%04d格式要求输入是整数类型,但你的year/mon/day列是numeric(带小数的数值类型,比如10.0),不是integer,所以触发了格式不匹配的错误。
其实lubridate提供了更简单的工具,根本不需要用sprintf拼接字符串——make_date()函数可以直接接收年、月、日的数值,自动处理NA和不同数值类型:
推荐解决方案:用lubridate的make_date()
这是最简洁可靠的方法,不需要手动处理字符串和格式符,直接传入三列即可:
library(lubridate) dt$date <- make_date(year = dt$year, month = dt$mon, day = dt$day)
它会自动忽略NA值,正确生成日期列,不管你的列是numeric还是integer类型都能正常工作。
如果一定要用你之前的sprintf思路,也可以先把列转成整数再处理:
library(lubridate) # 先转换为整数类型 dt[, c("year_int", "mon_int", "day_int") := lapply(.SD, as.integer), .SDcols = c("year", "mon", "day")] # 再生成日期 dt$date <- ymd(sprintf('%04d%02d%02d', year_int, mon_int, day_int))
不过显然make_date()的写法更清爽,推荐优先使用。
内容的提问来源于stack exchange,提问作者Sandhya Ghildiyal
相关产品推荐
相关产品推荐

