R语言如何新增变量存储数据框每条记录的最新可用日期
R语言逐行提取多列非空最晚日期实现方案
首先注意,初始构造的数据集里所有日期列是字符类型,直接比较大小可能出现排序错误,第一步先把所有日期列转为R标准Date类型,再逐行取最大值即可。
原始数据构造
ID<-1:5 Date1<-c(NA,NA,"2022-06-10",NA,NA) Date2<-c(NA,NA,NA,NA,NA) Date3<-c("2022-02-08",NA,NA,NA,NA) Date4<-c(NA,NA,"2022-06-24",NA,"2022-05-13") mydata<-data.frame(ID,Date1,Date2,Date3,Date4)
方法1:基础R实现(无需安装第三方包)
优先用向量化函数pmax()实现,大样本下运算效率远高于逐行遍历写法,代码最简洁:
# 匹配所有Date开头的日期列 date_cols <- grep("^Date", names(mydata), value = TRUE) # 批量转为标准日期格式 mydata[date_cols] <- lapply(mydata[date_cols], as.Date) # 逐行取非空日期的最大值,na.rm=TRUE自动忽略空值 mydata$last_date <- do.call(pmax, c(mydata[date_cols], na.rm = TRUE))
如果是小数据集,用apply逐行计算也可以实现:
mydata$last_date <- apply(mydata[date_cols], 1, function(row) { res <- max(row, na.rm = TRUE) ifelse(is.infinite(res), NA, res) })
方法2:tidyverse生态实现
如果日常使用dplyr等tidyverse包处理数据,可以用以下写法:
library(dplyr) mydata <- mydata %>% mutate(across(starts_with("Date"), as.Date), last_date = exec(pmax, !!!across(starts_with("Date")), na.rm = TRUE))
运行后输出结果和预期完全一致:
> mydata ID Date1 Date2 Date3 Date4 last_date 1 1 <NA> NA 2022-02-08 <NA> 2022-02-08 2 2 <NA> NA <NA> <NA> <NA> 3 3 2022-06-10 NA <NA> 2022-06-24 2022-06-24 4 4 <NA> NA <NA> <NA> <NA> 5 5 <NA> NA <NA> 2022-05-13 2022-05-13
关键提醒:所有涉及日期比较的操作,都要先把日期转为标准Date/POSIX类型,不要直接用字符串比较,否则遇到非
YYYY-MM-DD格式的日期时,会出现排序逻辑错误。
内容的提问来源于stack exchange,提问作者Seydou GORO
相关产品推荐
相关产品推荐

