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

如何将数据框的info字符串列拆分为年、月、日列?

问题描述

现有如下数据集,其中info列包含类似PRISM_ppt_provisional_4kmD2_20220925_bil的字符串,需要将该列拆分为year(年)、month(月)、day(日)列:

df = structure(list(id = c(1, 2, 3, 4, 5, 6, 7, 8), info = c("PRISM_ppt_provisional_4kmD2_20220925_bil", 
"PRISM_ppt_provisional_4kmD2_20220926_bil", "PRISM_ppt_provisional_4kmD2_20220927_bil", 
"PRISM_ppt_provisional_4kmD2_20220928_bil", "PRISM_ppt_provisional_4kmD2_20220929_bil", 
"PRISM_ppt_provisional_4kmD2_20220930_bil", "PRISM_ppt_provisional_4kmD2_20220925_bil", 
"PRISM_ppt_provisional_4kmD2_20220926_bil")), class = "data.frame", row.names = c(NA, 
-8L))

期望得到的结果如下:

desired_df = structure(list(id = c(1, 2, 3, 4, 5, 6, 7, 8), info = c("PRISM_ppt_provisional_4kmD2_20220925_bil", 
"PRISM_ppt_provisional_4kmD2_20220926_bil", "PRISM_ppt_provisional_4kmD2_20220927_bil", 
"PRISM_ppt_provisional_4kmD2_20220928_bil", "PRISM_ppt_provisional_4kmD2_20220929_bil", 
"PRISM_ppt_provisional_4kmD2_20220930_bil", "PRISM_ppt_provisional_4kmD2_20220925_bil", 
"PRISM_ppt_provisional_4kmD2_20220926_bil"), year = c(2022, 2022, 
2022, 2022, 2022, 2022, 2022, 2022), month = c(9, 9, 9, 9, 9, 
9, 9, 9), day = c(25, 26, 27, 28, 29, 30, 25, 26)), class = "data.frame", row.names = c(NA, 
-8L))

尝试用separate函数但不知道sep参数该如何设置:

# Extract year, month and day from info column
df = separate(df, info, into = c("year", "month", "day"), sep = ?, convert = T)
解决方案

因为info列中的日期是连续的8位数字(格式为YYYYMMDD),没有明确分隔符,所以需要先提取出这部分日期字符串,再拆分为年、月、日。以下是几种可行的方法:

方法1:使用separate结合正则表达式

可以先提取日期部分再拆分,同时保留原info列:

library(tidyr)
library(stringr)

df <- df %>%
  mutate(date_str = str_extract(info, "\\d{8}")) %>%
  separate(date_str, into = c("year", "month", "day"), sep = c(4, 6), convert = TRUE)

也可以直接在separate中用正则定位拆分位置,忽略非日期部分:

df <- separate(df, info, 
               into = c("drop", "year", "month", "day", "drop2"), 
               sep = c(".*_(?=\\d{4})", 4, 2), 
               convert = TRUE,
               remove = FALSE) %>%
  select(-drop, -drop2)

方法2:使用lubridate规范处理日期

借助lubridate包将日期字符串转为标准日期格式,再提取年、月、日:

library(tidyr)
library(lubridate)
library(stringr)

df <- df %>%
  mutate(date = ymd(str_extract(info, "\\d{8}")),
         year = year(date),
         month = month(date),
         day = day(date)) %>%
  select(-date) # 不需要date列可删除该行

方法3:基础R字符串操作

如果不想加载额外包,用基础R函数即可完成:

# 提取8位日期字符串
date_str <- substr(df$info, nchar(df$info)-12, nchar(df$info)-5)

# 拆分年、月、日并转为数值型
df$year <- as.integer(substr(date_str, 1, 4))
df$month <- as.integer(substr(date_str, 5, 6))
df$day <- as.integer(substr(date_str, 7, 8))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 16:55:36