我有很多数据框,其中的多个列包含日期,区域,产品和销售数量,涵盖不同的行业。这是我在说的一个简化示例
Year = c((rep(c(2015),5)),(rep(c(2015)+1,5)),(rep(c(2015)+2,5)))
Month = as.factor(c("JAN","FEB","MAR","APR","MAY"))
Week = as.factor(c(1,2,3,4,5))
product_type = as.factor(c("Yellow", "Green", "Red", "Blue", "Black"))
region = as.factor(c("North","North","North","South","South"))
Sales = c(1000,2000,3000,4000,5000,1500,2200,2800,4500,2000,3000,4000,5000,6000,5200)
df = data.frame(date,product_type,region,Sales)
df
Year Month Week product_type region Sales
1 2015 JAN 1 Yellow North 1000
2 2015 FEB 2 Green North 2000
3 2015 MAR 3 Red North 3000
4 2015 APR 4 Blue South 4000
5 2015 MAY 5 Black South 5000
6 2016 JAN 1 Yellow North 1500
7 2016 FEB 2 Green North 2200
8 2016 MAR 3 Red North 2800
9 2016 APR 4 Blue South 4500
10 2016 MAY 5 Black South 2000
11 2017 JAN 1 Yellow North 3000
12 2017 FEB 2 Green North 4000
13 2017 MAR 3 Red North 5000
14 2017 APR 4 Blue South 6000
15 2017 MAY 5 Black South 5200
我正在尝试为此数据计算y / y变化,并按product_type和region进行过滤。再一次,这是一个更加简单的版本,我拥有多年以来每种产品和地区的52周数据。结果应如下所示。
Year Month Week product_type region Sales y/y
2016 JAN 1 Yellow North 1500 50.0%
2016 FEB 2 Green North 2200 10.0%
2016 MAR 3 Red North 2800 ---
2016 APR 4 Blue South 4500 ---
2016 MAY 5 Black South 2000
2017 JAN 1 Yellow North 3000
2017 FEB 2 Green North 4000
2017 MAR 3 Red North 5000
2017 APR 4 Blue South 6000
2017 MAY 5 Black South 5200
我的问题是,不同的数据集具有不同的长度,可能一年缺少一些数据,或者名称完全不同。
到目前为止,我的解决方案是使用data.table和tidyverse库过滤出一个“ product_type”和一个“区域”,然后使用shift()计算一个日期与另一个日期的差。这就需要我创建新的数据框架,需要过滤的硬代码,这会使我的代码太长,以至于其他人都无法理解或检查。由于我的实际数据集具有数百万行的数据,因此该解决方案还需要我花费相当多的时间编写代码并在markdown中运行。
这是我正在处理的列的示例
"Company","Date","Year","Month","Week","Region","Product Type","Company Sales Units",
"Company Value USD","Company ASP","Total Sales Units","Total Value USD","Total ASP",
"% Share Units","% Share USD","ASP difference"
我想知道是否有一种方法可以执行计算,但是要求“ product_type”和“ region”值都相同,但是日期不同。能做到吗?如果没有,可以使用SQL或python完成吗?我在这两者上都有一些经验,但是非常生锈。
任何建议也将有所帮助,谢谢!
尝试这个:
df <- df %>%
group_by(product_type, region) %>%
mutate("y/y" = if_else(Year == (lag(Year) + 1), (Sales/lag(Sales)) - 1, NA_real_))%>%
group_by(Year) %>%
mutate(month_num = match(Month, toupper(month.abb))) %>%
mutate("m/m" = if_else(month_num == lag(month_num) + 1, (Sales/lag(Sales)) - 1, NA_real_)) %>%
mutate("w/w" = if_else(Week == (lag(Week) + 1), (Sales/lag(Sales)) - 1, NA_real_))
df
滞后会查看上一行,如果您按产品类型和地区进行分组,则会查看每个组的前一行。
例如,如果product_type和region为Yellow和North,则将2016年的销售数量除以2015年的销售数量(并减去1,因此是.5而不是1.5)。
如果跳过一年,if_else将会捕获,并且如果年份是连续的,则仅计算y / y%。使用if_else(与基础ifelse相反)要求true和false值是同一类型,因此使用NA_real_
。
逻辑可以理解为:如果当前组行日期等于前一行的日期+ 1(2016 == 2015 + 1),则计算y / y%,否则计算NA。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句