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

在R语言中将日期转换为年-月格式并保留日期类型

解决日期列保留年-月日期类型的问题

我来帮你搞定这个问题!你遇到的核心问题是:strftime确实会把日期对象转换成字符型,而直接用as_datetime处理%Y-%m格式的字符串时,因为缺少“日”的信息,lubridate无法正确解析,所以返回了NA。下面给你几种可行的解决方案:

方案1:使用专门的年月类型(zoo包的yearmon)

yearmon是zoo包中专门用于表示“年-月”的日期类型,它既保留了日期的属性,又不会包含多余的“日”信息,完美匹配你的需求:

library(lubridate)
library(zoo)

# 你的原始数据
df <- data.frame(Date=c("2017-01-01","2017-01-02","2017-01-03","2017-01-04", 
                        "2018-01-01","2018-01-02","2018-02-01","2018-03-02"), 
                 N=c(24,10,13,12,10,10,33,45))

# 方式1:先转成lubridate日期,再转yearmon
df$Date <- as.yearmon(ymd(df$Date))

# 方式2:直接从原始字符串转yearmon,更高效
df$Date <- as.yearmon(df$Date, "%Y-%m-%d")

# 查看类型,确认是yearmon而非字符型
class(df$Date)

这种类型支持日期相关的运算(比如排序、加减月份),而且默认显示就是%Y-%m格式。

方案2:保留lubridate日期类型,仅显示年月

如果你想继续使用lubridate的日期/日期时间类型,可以用floor_date把日期统一到当月第一天,然后控制显示格式:

library(lubridate)

df <- data.frame(Date=c("2017-01-01","2017-01-02","2017-01-03","2017-01-04", 
                        "2018-01-01","2018-01-02","2018-02-01","2018-03-02"), 
                 N=c(24,10,13,12,10,10,33,45))

# 将所有日期转换为当月第一天的日期对象
df$Date <- floor_date(ymd(df$Date), unit = "month")

# 如果需要打印时显示为%Y-%m格式,可以指定format参数
print(df$Date, format = "%Y-%m")

# 分组统计时也完全不受影响
df %>% 
  group_by(Date) %>% 
  summarise(total_N = sum(N))

为什么你的as_datetime会返回NA?

当你用strftime得到%Y-%m格式的字符串后,直接传给as_datetime时,lubridate不知道如何处理缺少“日”的日期字符串。如果一定要解析这种格式,需要显式指定格式:

# 解析%Y-%m格式的字符串,默认日为01
as_datetime("2017-01", format = "%Y-%m")

但这种方式其实和floor_date的效果一致,不如直接用floor_date更直观。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:46:37