使用dplyr根据年月生成每月最后一天ymd格式新列的问题
解决基于yearmon格式列生成每月最后日期的问题
需求说明
基于数据框中已有的month_year列(yearmon格式),为每行生成新列end_month,展示对应月份最后一天的dd/mm/yyyy格式日期,示例如下:
| month_year | end_month |
|---|---|
| Jan 2022 | 31/01/2022 |
| Feb 2022 | 28/02/2022 |
| March 2022 | 31/03/2022 |
数据框结构示例:
structure(list(id = 1:20, posted_date = c("2023-03-12 00:00:00", "2023-03-13 00:00:00", "2023-03-20 00:00:00", "2023-03-08 00:00:00", "2023-03-16 00:00:00", "2023-03-20 00:00:00", "2023-03-09 00:00:00", "2023-03-20 00:00:00", "2023-03-13 00:00:00", "2023-03-21 00:00:00", "2023-03-07 00:00:00", "2023-03-08 00:00:00", "2023-03-19 00:00:00", "2023-03-19 00:00:00", "2023-03-12 00:00:00", "2023-03-12 00:00:00", "2023-03-20 00:00:00", "2023-03-20 00:00:00", "2023-03-09 00:00:00", "2023-03-12 00:00:00"), month_year = structure(c(2023.16666666667, 2023.16666666667, 2023.16666666667, 2023.16666666667, 2023.16666666667, 2023.16666666667, 2023.16666666667, 2023.16666666667, 2023.16666666667, 2023.16666666667, 2023.16666666667, 2023.16666666667, 2023.16666666667, 2023.16666666667, 2023.16666666667, 2023.16666666667, 2023.16666666667, 2023.16666666667, 2023.16666666667, 2023.16666666667), class = "yearmon")), row.names = c(NA, -20L), class = c("tbl_df", "tbl", "data.frame"))
报错原因
你尝试的代码存在两个关键问题:
- 代码中使用了
as.yearmon(Date),但你的数据框里没有名为Date的列,且Date是R内置的构造函数(属于closure类型),把函数当作变量传入就会触发cannot coerce type 'closure' to vector of type 'double'的错误。 - 你的需求是为每行添加最后日期,不需要用
summarise做分组汇总,且数据中已经存在month_year列,无需重新生成。
正确解决方案
方法1:利用zoo包原生功能(推荐)
zoo的as.Date.yearmon函数支持通过frac=1直接获取当月最后一天,再用format转换为目标格式:
job_posts %>% mutate(end_month = format(as.Date(month_year, frac = 1), "%d/%m/%Y"))
frac=1:指定取当月最后一天(frac=0则取当月第一天)"%d/%m/%Y":定义输出格式为日/月/年
方法2:结合lubridate包函数
先将yearmon转为当月第一天,再通过ceiling_date获取下月第一天,减1天得到当月最后一天:
library(lubridate) job_posts %>% mutate( end_month = format( ceiling_date(as.Date(month_year), "month") - days(1), "%d/%m/%Y" ) )
两种方法都会自动处理闰年(比如2020年2月会返回29/02/2020),最终为每行生成对应的月末日期。
内容的提问来源于stack exchange,提问作者nesta1990
相关产品推荐
相关产品推荐

