如何用transform批量处理多数据框的异常格式日期并保留全列?
日期格式转换及数据类型处理问题
模拟数据
my_list <- list(structure(list(start = c("2023-09-12T18:59:49.336+01:00", "2023-09-18 07:29:34", "z2023-09-18 07:29:34"), country = c("USA", "UK", "UK")), class = "data.frame", row.names = c(NA, -3L)), structure(list(start = c("2023-09-16T21:12:51.288Z", "2019-11-30", "2019-30-11"), country = c("UK", "Canada", "France")), class = "data.frame", row.names = c(NA, -3L)))
尝试方案及问题
参考相关方案后,使用anytime包尝试转换日期格式,代码如下:
library(anytime) lapply(my_list, transform, start = anydate(start) )
但部分异常格式的日期被转为NA,输出结果:
[[1]] start country 1 2023-09-12 USA 2 2023-09-18 UK 3 <NA> UK [[2]] start country 1 2023-09-16 UK 2 2019-11-30 Canada 3 <NA> France
期望输出
[[1]] start country 1 2023-09-12 USA 2 2023-09-18 UK 3 2023-09-18 UK [[2]] start country 1 2023-09-16 UK 2 2019-11-30 Canada 3 2019-11-30 France
需求说明
- 需保留数据框中的所有列,不能仅返回日期列
- 优先使用
transform函数,同时支持修改其他变量(例如将country转为因子类型) - 最终结果需确保
start为Date类型、country为Factor类型 - 解决方案不局限于
anytime包
解决方案
自定义日期处理函数
针对两种异常日期格式(前缀含无关字符、日月颠倒),编写自定义解析函数:
clean_and_parse_date <- function(date_str) { # 清除字符串开头的非日期字符(如"z") cleaned_str <- gsub("^[^0-9-]+", "", date_str) # 尝试多种常见格式解析日期 parsed_date <- as.Date(cleaned_str, tryFormats = c( "%Y-%m-%dT%H:%M:%OS%z", "%Y-%m-%d %H:%M:%S", "%Y-%m-%d", "%Y-%d-%m" )) # 对仍未解析成功的日期,尝试交换日月位置后再解析 na_pos <- is.na(parsed_date) if (any(na_pos)) { swapped_str <- gsub("(\\d{4})-(\\d{2})-(\\d{2})", "\\1-\\3-\\2", cleaned_str[na_pos]) parsed_date[na_pos] <- as.Date(swapped_str) } return(parsed_date) }
应用转换逻辑
结合lapply和transform完成批量处理,同时转换country为因子类型:
lapply(my_list, transform, start = clean_and_parse_date(start), country = as.factor(country) )
结果验证
运行上述代码后,将得到与期望一致的输出,且:
start列为标准Date类型country列转为Factor类型- 所有原始列均被保留
内容的提问来源于stack exchange,提问作者johnjohn
相关产品推荐
相关产品推荐

