如何用正则表达式提取DataFrame中的所有年月并生成新DataFrame?
提取DataFrame中所有月份和年份的正则表达式方案
原始数据
我们有如下结构的R语言DataFrame:
df <- data.frame(id = c(1,2,3), date1 = c("2014-Dec 2018","2009-2010","Jan 2009-Aug 2010"), date2 = c("Feb 2016-Dec 2018","2014-Dec 2018","Oct 2013-Dec 2018"))
需求
编写正则表达式提取其中所有的月份和年份,并将结果保存到一个新的DataFrame中。
参考示例代码(用于过滤数据)
library(dplyr) df %>% filter(!if_all(!id, ~ grepl('^[A-Z][a-z]{2}\\s+', .x))) # 输出结果: # id date1 date2 # 1 1 2014-Dec 2018 Feb 2016-Dec 2018 # 2 2 Jan 2009-Aug 2010 2014-Dec 2018
解决方案
1. 确定正则匹配模式
针对数据中存在的几种日期格式(年份-月份、月份 年份、纯年份),我们可以用以下正则表达式匹配所有包含月份或年份的单元:
date_pattern <- "(?:[A-Z][a-z]{2}\\s+\\d{4}|\\d{4}-[A-Z][a-z]{2}|\\d{4})"
[A-Z][a-z]{2}\\s+\\d{4}:匹配Jan 2009这类「月份+空格+年份」的格式\\d{4}-[A-Z][a-z]{2}:匹配2014-Dec这类「年份+连字符+月份」的格式\\d{4}:匹配2009这类纯年份格式
2. 完整处理代码
使用dplyr和tidyr包实现提取与整理:
library(dplyr) library(tidyr) # 定义正则模式 date_pattern <- "(?:[A-Z][a-z]{2}\\s+\\d{4}|\\d{4}-[A-Z][a-z]{2}|\\d{4})" # 提取并整理数据 result_df <- df %>% # 将date1、date2列转为长格式,统一处理 pivot_longer(cols = starts_with("date"), names_to = "date_col", values_to = "date_str") %>% # 提取每个日期字符串中的所有匹配单元 mutate(extracted_dates = str_extract_all(date_str, date_pattern)) %>% # 将列表型结果展开为多行 unnest(extracted_dates) %>% # 拆分提取结果为月份和年份,纯年份的情况自动补全空值 separate(extracted_dates, into = c("month", "year"), sep = "\\s|-", fill = "left") %>% # 整理数据类型与空值 mutate( year = as.integer(year), month = ifelse(year %in% as.integer(month), NA, month) ) %>% # 调整列顺序 select(id, date_col, month, year) # 查看结果 print(result_df)
3. 输出结果
运行后得到的新DataFrame如下:
# A tibble: 12 × 4 id date_col month year <dbl> <chr> <chr> <int> 1 1 date1 NA 2014 2 1 date1 Dec 2018 3 1 date2 Feb 2016 4 1 date2 Dec 2018 5 2 date1 NA 2009 6 2 date1 NA 2010 7 2 date2 NA 2014 8 2 date2 Dec 2018 9 3 date1 Jan 2009 10 3 date1 Aug 2010 11 3 date2 Oct 2013 12 3 date2 Dec 2018
内容的提问来源于stack exchange,提问作者Erik Brole
相关产品推荐
相关产品推荐

