问题描述
对于两个不同的年份,对于每一年,我需要对从 1 月 3 日到 3 月 3 日发生的所有销售额求和。我更喜欢 dplyr 解决方案。
我在 stackoverflow 中看到的所有可能的解决方案都使用 sql,而不是 R。如果有人知道我遗漏的解决方案,请告诉我。
在 R 中,我知道如何与组一起工作并使用各种 dplyr 函数,但我需要帮助来完成这篇文章的内容。
我希望输出看起来像这样:
Year Total Sales
2020 138
2021 196
输入
df <- data.frame(date=c(20200102,20200107,20200210,20200215,20200216,20200302,20200305,20210101,20210104,20210209,20210211,20210215,20210317,20210322),sales=c(9,14,27,30,33,34,36,44,45,47,51,53,56,58))
解决方法
比我的主 akrun 的解决方案少一行 :)
- 使用
ymd
包的lubridate
函数将字符类型转换为日期。 - 使用
DayMonth
函数仅考虑月和日所需的月日间隔 - 按
year
分组 - 过滤间隔
- 总结
library(lubridate)
df %>%
mutate(date = ymd(date)) %>%
mutate(DayMonth = format(as.Date(date),"%m-%d")) %>%
group_by(Year=year(date)) %>%
filter(DayMonth>"01-03" & DayMonth<"03-03") %>%
summarise(Total_Sales = sum(sales))
输出:
Year Total_Sales
<int> <dbl>
1 2020 138
2 2021 196
,
您也可以使用以下解决方案:
library(dplyr)
library(lubridate)
df %>%
mutate(date = ymd(date)) %>%
group_by(year = year(date)) %>%
filter(date %within% interval(ymd(paste(first(year),"01-03",sep = "-")),ymd(paste(first(year),"03-03",sep = "-")))) %>%
summarise(sale = sum(sales))
# A tibble: 2 x 2
year sale
<dbl> <dbl>
1 2020 138
2 2021 196
,
我们可以使用tidyverse
。将“日期”转换为 Date
类(使用 ymd
中的 lubridate
),从“日期”中获取 month
和 day
,创建一个新日期将 ISOdate
和 year
标准化为单一年份(这里我们选择了 2021 - 可以是任何年份),然后我们使用 filter
between
'newdate' 并指定left
和 right
参数作为自定义日期范围,然后按 'year' 进行分组并在 sum
summarise
library(dplyr)
library(lubridate)
df %>%
mutate(date = ymd(date),year = year(date),month = month(date),day = day(date),newdate = as.Date(ISOdate(2021,month,day))) %>%
filter(between(newdate,as.Date("2021-01-03"),as.Date("2021-03-03"))) %>%
group_by(year) %>%
summarise(sales = sum(sales))
-输出
# A tibble: 2 x 2
# year sales
# <dbl> <dbl>
#1 2020 138
#2 2021 196
或者使用 aggregate
中的 base R
。通过 sub
情况创建 'newdate',即从 'date' 的开头 (.{4}
) 删除前 4 个字符 (^
),替换为 '2021',转换为 { {1}} 类,使用关系运算符执行 Date
。然后使用 subset
中过滤后的数据集通过 aggregate
部分即前 4 个字符获取 'sales' 的 sum
year
,
仅使用整数/模除法、%%
和 %/%
的简单解决方案,即不使用任何日期类型库(lubridate 等)
- 由于您的日期变量遵循最合乎逻辑的(并且最适合日期的 aplhabetical 排序)格式,因此这里的工作是检查前四位数字的条件/分组,过滤后四位数字并进行汇总。所以
-
group_by
onYear
这是通过整数除法获得的,即%/%
日期除以10000
这将始终为您提供前四位数字(在 YYYYMMDD 格式的情况下)立> - 无需先创建此列,然后再创建 group_by
- 然后使用
%%
的模除法date
通过10000
获得最后四位数字来过滤行并检查您的条件 - 最后总结
- 如果您的日期列是字符类型,请在所有步骤中用
as.numeric
将其包裹
library(dplyr)
df %>%
group_by(Year = date %/% 10000) %>%
filter(date %% 10000 > 103,date %% 10000 < 303) %>%
summarise(Total_sales = sum(sales))
#> # A tibble: 2 x 2
#> Year Total_sales
#> <dbl> <dbl>
#> 1 2020 138
#> 2 2021 196
由 reprex package (v2.0.0) 于 2021 年 5 月 30 日创建
等效的 baseR 语法
aggregate(sales ~ cbind(Year = date %/% 10000),subset(df,date %% 10000 > 103 & date %% 10000 < 303),FUN = sum)
Year sales
1 2020 138
2 2021 196