R语言日期序列函数修正及客户时间段按月拆分问询
解决方案
没问题,我帮你一步步搞定这个需求:
第一步:修正datseq函数
你的原函数有两个小问题需要调整:
- 拼写错误:
as.Data应该是as.Date(R里的日期函数是大写D的Date) - 格式转换:
seq生成的是Date类型的对象,我们需要把它转成YYYYMM的格式(可以是字符型,要是需要数值的话再加个as.numeric()就行)
修正后的函数如下:
datseq <- function(t1, t2) { # 生成月度日期序列,先把输入转成正确的Date类型 date_sequence <- seq(as.Date(t1), as.Date(t2), by = "month") # 把日期格式化为YYYYMM的字符串 format(date_sequence, "%Y%m") }
你可以先测试下这个函数:
datseq("2015-01-01", "2015-03-01") # 输出会是:[1] "201501" "201502" "201503"
第二步:把函数应用到整个数据框,拆分时间段
接下来要把每一行的起止日期传入函数,生成对应的年月序列,再把这些序列展开成单独的行。这里推荐用tidyverse工具包(dplyr + tidyr),代码简洁又好维护:
首先先把你的原始数据整理成数据框:
library(tidyverse) # 构造原始数据(第二列没列名,我暂时叫它col2,你可以改成自己需要的名字) customer_data <- tibble( customer_id = c(11, 11, 22), col2 = c(22, 55, 33), startdate = c("2015-01-01", "2018-04-03", "2017-02-01"), enddate = c("2015-03-01", "2018-06-16", "2017-04-01") )
然后用mutate生成年月序列,再用unnest_longer把序列拆成单独的行:
final_result <- customer_data %>% # 对每一行的startdate和enddate应用datseq函数,生成年月序列 mutate(YearMonth = map2(startdate, enddate, datseq)) %>% # 把序列展开成多行 unnest_longer(YearMonth) %>% # 调整列顺序到你期望的格式 select(customer_id, col2, YearMonth) # 查看结果 print(final_result)
输出结果就和你期望的完全一致啦:
# A tibble: 9 × 3 customer_id col2 YearMonth <dbl> <dbl> <chr> 1 11 22 201501 2 11 22 201502 3 11 22 201503 4 11 55 201804 5 11 55 201805 6 11 55 201806 7 22 33 201702 8 22 33 201703 9 22 33 201704
要是不想用第三方包,用基础R也能实现
如果你不想依赖tidyverse,用基础R的apply函数也能搞定:
# 定义处理单行数据的函数 process_single_row <- function(row) { # 生成年月序列 ym_sequence <- datseq(row["startdate"], row["enddate"]) # 生成对应行数的结果行 data.frame( customer_id = rep(row["customer_id"], length(ym_sequence)), col2 = rep(row["col2"], length(ym_sequence)), YearMonth = ym_sequence, stringsAsFactors = FALSE ) } # 对每一行应用函数,然后合并结果 result_base_r <- do.call(rbind, apply(customer_data, 1, process_single_row))
这样得到的结果和上面是一样的~
内容的提问来源于stack exchange,提问作者Jordan1200
相关产品推荐
相关产品推荐

