如何用R将季度日期在季度首日与末日之间互转?
R语言实现季度首日与末日日期互转
前提准备
首先需将数据框中的字符型日期转换为Date类型,后续所有日期操作均基于该类型:
# 加载示例数据 df1 <- structure(list(date = c("2010-3-31", "2010-6-30", "2010-9-30", "2010-12-31", "2011-3-31", "2011-6-30", "2011-9-30", "2011-12-31"), value = c(24.1, 16.4, 18.5, 8.61, 12.6, 20.1, 17.9, 14.5)), class = "data.frame", row.names = c(NA, -8L)) df2 <- structure(list(date = c("2010-1-1", "2010-4-1", "2010-7-1", "2010-10-1", "2011-1-1", "2011-4-1", "2011-7-1", "2011-10-1"), value = c(24.1, 16.4, 18.5, 8.61, 12.6, 20.1, 17.9, 14.5)), class = "data.frame", row.names = c(NA, -8L)) # 转换日期类型 df1$date <- as.Date(df1$date) df2$date <- as.Date(df2$date)
一、季度末日转季度首日
方法1:使用lubridate包(推荐)
lubridate包的floor_date()函数可直接将日期向下取整到指定周期,指定"quarter"即可得到对应季度的首日:
library(lubridate) df1_to_start <- df1 df1_to_start$date <- floor_date(df1_to_start$date, "quarter") # 查看结果 print(df1_to_start)
输出结果:
date value 1 2010-01-01 24.10 2 2010-04-01 16.40 3 2010-07-01 18.50 4 2010-10-01 8.61 5 2011-01-01 12.60 6 2011-04-01 20.10 7 2011-07-01 17.90 8 2011-10-01 14.50
方法2:Base R实现
通过提取年份和季度,计算对应季度的首日:
df1_to_start_base <- df1 # 提取季度 quarter_num <- as.POSIXlt(df1_to_start_base$date)$mon %/% 3 + 1 # 计算季度首日 df1_to_start_base$date <- as.Date(paste0(year(df1_to_start_base$date), "-", (quarter_num-1)*3 + 1, "-01")) print(df1_to_start_base)
输出结果与方法1一致。
二、季度首日转季度末日
方法1:使用lubridate包(推荐)
ceiling_date()函数将日期向上取整到下一个季度,再减去1天即可得到当前季度的末日:
df2_to_end <- df2 df2_to_end$date <- ceiling_date(df2_to_end$date, "quarter") - days(1) # 查看结果 print(df2_to_end)
输出结果:
date value 1 2010-03-31 24.10 2 2010-06-30 16.40 3 2010-09-30 18.50 4 2010-12-31 8.61 5 2011-03-31 12.60 6 2011-06-30 20.10 7 2011-09-30 17.90 8 2011-12-31 14.50
方法2:Base R实现
通过提取年份和季度,计算对应季度的最后一天:
df2_to_end_base <- df2 # 提取季度 quarter_num <- as.POSIXlt(df2_to_end_base$date)$mon %/% 3 + 1 # 计算季度末日:下一个季度首日减1天 next_quarter_month <- quarter_num*3 + 1 next_quarter_year <- year(df2_to_end_base$date) # 处理四季度的情况(下一年1月) next_quarter_year <- ifelse(next_quarter_month > 12, next_quarter_year + 1, next_quarter_year) next_quarter_month <- ifelse(next_quarter_month >12, 1, next_quarter_month) df2_to_end_base$date <- as.Date(paste0(next_quarter_year, "-", next_quarter_month, "-01")) - 1 print(df2_to_end_base)
输出结果与方法1一致。
内容的提问来源于stack exchange,提问作者ah bon
相关产品推荐
相关产品推荐

