如何解决在R中,如何根据不同的列标准计算数据框中的y / y和w / w?
我有很多数据框,其中包含多列,其中包含日期,地区,产品和销售数量,涵盖了不同的行业。这是我在说什么的简化示例
pick
我正在尝试为此数据计算y / y变化,并按product_type和region进行过滤。再一次,这是一个更加简单的版本,我拥有多年以来每种产品和地区的52周数据。结果应如下所示。
Year = c((rep(c(2015),5)),(rep(c(2015)+1,(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","South","South"))
Sales = c(1000,2000,3000,4000,5000,1500,2200,2800,4500,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
我的问题是,不同的数据集具有不同的长度,可能缺少一年的数据,或者名称完全不同。
到目前为止,我的解决方案是使用data.table和tidyverse库过滤出一个“ product_type”和一个“区域”,然后使用shift()计算一个日期与另一个日期的差。这就需要我创建新的数据框架,需要过滤的硬代码,这会使我的代码太长,以至于其他人都无法理解或检查。由于我的实际数据集包含数百万行数据,因此该解决方案还需要我花费一些时间来编写代码并在markdown中运行。
这是我正在处理的列的示例
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
我想知道是否有一种方法可以执行计算,但是要求“ 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,NA_real_)) %>%
mutate("w/w" = if_else(Week == (lag(Week) + 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。
,这使用data.table,但是如果您愿意,可以使用dplyr进行
library(data.table)
setDT(df)
df[order(date),.(
date = tail(date,-1),`y/y` = 100*(exp(diff(log(Sales))/diff(date))-1)
),.(product_type,region)]
该公式通过假设从一个数据点到下一个数据点的整个期间的常数y/y
返回常数来说明缺少的年份。
对于更新的数据集,这是一个稍有不同的问题-大概是每周销售,因此,如果您希望按年或按月更改,则必须首先进行一些汇总。
对于每周的计算,您只需要计算要放入顺序日期列中的内容,也许是df[,date := (Year - 2015)*52 + Week]
,然后上面的代码就会起作用。或者,也许您可以计算出每一行所指的实际一周的第一天并使用它。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。