You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在R数据框中从混合格式日期提取年份(含Excel序列号)

问题:从多格式日期字段中提取年份,处理Excel日期序列号

我正在清理一个混乱的数据库,其中变量inicio包含多种日期输入格式,例如:"MAR 23"、"1º Sem 2021"、"OUT/21"、"41365",需要提取所有日期对应的年份。

已尝试的方法及问题

1. 正则提取函数

用正则提取末尾两位数字作为年份,代码如下:

# 提取末尾两位数字(仅年份)
pattern <- "\\b\\d{2}$"

# 正则提取年份的函数
extract_years <- function(text, pattern) {
  matches <- regmatches(text, gregexpr(pattern, text))
  years <- sapply(matches, function(x) as.numeric(x))
  return(years)
}

# 使用dplyr从日期列提取年份
informex_clean_2 <- informex_clean |>
  mutate(ano = extract_years(inicio, pattern))

该函数对"MAR 23"、"OUT/21"、"1º Sem 2021"这类格式有效,但对"41365"这类Excel日期序列号会返回NA。

2. 日期转换函数尝试

尝试写了转换函数,但对"41365"仍返回NA:

# 尝试转换为日期的自定义函数
convert_to_date_if_possible <- function(x) {
  if (is.numeric(x)) {
    # 若输入为数值,假设是日期表示并尝试转换
    x_date <- as.Date(as.numeric(x), origin = "1899-12-30") # Excel日期原点为1899-12-30
    if (!is.na(x_date)) {
      # 转换成功,返回日期对象
      return(x_date)
    } else {
      # 转换失败,返回原始字符值
      return(x)
    }
  } else {
    # 输入非数值,返回原始字符值
    return(x)
  }
}

问题核心:"41365"在数据中是字符类型,is.numeric(x)判断为FALSE,无法进入转换逻辑。

解决方案

下面是修正后的完整年份提取函数,能处理所有上述格式:

library(dplyr)
library(lubridate)
library(stringr)

extract_year <- function(x) {
  # 处理Excel日期序列号(字符型转数值后转日期)
  num_x <- suppressWarnings(as.numeric(x))
  if (!is.na(num_x)) {
    return(year(as.Date(num_x, origin = "1899-12-30")))
  }
  
  # 提取4位完整年份(如"1º Sem 2021"中的2021)
  full_year <- suppressWarnings(as.numeric(str_extract(x, "\\b20\\d{2}\\b")))
  if (!is.na(full_year)) {
    return(full_year)
  }
  
  # 提取两位年份并补全为4位(默认2000年后,可按需调整)
  two_digit <- suppressWarnings(as.numeric(str_extract(x, "\\b\\d{2}\\b")))
  if (!is.na(two_digit)) {
    # 若需区分19xx/20xx,可加判断:two_digit > 50 则 1900 + two_digit,否则2000 + two_digit
    return(2000 + two_digit)
  }
  
  # 无匹配时返回NA
  return(NA_integer_)
}

# 应用到数据框
informex_clean_2 <- informex_clean |>
  mutate(ano = extract_year(inicio))

关键说明

  • 先尝试将输入转为数值,解决字符型Excel序列号的转换问题;
  • 优先提取4位年份,避免两位年份的歧义;
  • 两位年份默认补2000,若数据包含19xx年份,可修改逻辑区分;
  • 用suppressWarnings()屏蔽转换失败的警告,不影响最终输出。

内容的提问来源于stack exchange,提问作者Paula Macedo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 14:36:30