我有一个与价格的有效开始和结束月份(持续时间)相关的 R 数据集。下面是一个例子:
print(df)
Customer Product Price Start_Month End_Month
ABC XYZ 100 Jan Jun
ABC XYZ 150 Jul Dec
我需要编写可以每月扩展此表的代码/函数。我的预期结果如下:
Customer Product Price Month
ABC XYZ 100 Jan
ABC XYZ 100 Feb
ABC XYZ 100 Mar
ABC XYZ 100 Apr
ABC XYZ 100 May
ABC XYZ 100 Jun
ABC XYZ 150 Jul
ABC XYZ 150 Aug
ABC XYZ 150 Sep
ABC XYZ 150 Oct
ABC XYZ 150 Nov
ABC XYZ 150 Dec
我找不到其他类似的问题可以帮助我解决我的问题。
最佳答案
一种 tidyverse
方法是将数据帧转换为长格式,这样我们现在原始数据帧中的每一行都有两行。现在,对于每一行,我们使用 match
来获取开始月和结束月中月份值的索引,然后使用它创建一个序列。
library(tidyverse)
df %>%
gather(key, Month, -(1:3)) %>%
group_by_at(1:3) %>%
complete(Month = month.abb[match(Month[1], month.abb):
match(Month[2], month.abb)]) %>%
arrange(Customer, Product, Price, match(Month, month.abb)) %>%
select(-key)
# Customer Product Price Month
# <fct> <fct> <int> <chr>
# 1 ABC XYZ 100 Jan
# 2 ABC XYZ 100 Feb
# 3 ABC XYZ 100 Mar
# 4 ABC XYZ 100 Apr
# 5 ABC XYZ 100 May
# 6 ABC XYZ 100 Jun
# 7 ABC XYZ 150 Jul
# 8 ABC XYZ 150 Aug
# 9 ABC XYZ 150 Sep
#10 ABC XYZ 150 Oct
#11 ABC XYZ 150 Nov
#12 ABC XYZ 150 Dec
或者使用map2
的另一个选项
df %>%
mutate(Month = map2(Start_Month, End_Month,
~month.abb[match(.x, month.abb) : match(.y, month.abb)])) %>%
unnest() %>%
select(-Start_Month, -End_Month)
在基础 R 中将使用 Map
do.call(rbind, Map(function(x, y, z) cbind(df[z,],
Month = month.abb[match(x, month.abb) : match(y, month.abb)]),
df$Start_Month, df$End_Month, seq_len(nrow(df))))
在这里,我们利用内置的 month.abb
向量来获取序列
month.abb
# [1] "Jan" "Feb" "Mar" "Apr" "May" "Jun" "Jul" "Aug" "Sep" "Oct" "Nov" "Dec"
关于R函数用于按月扩展表,给定开始月份和结束月份,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55877280/