使用 R,对于每一年,我需要总结相同两个日期之间不同年份的销售额

问题描述

对于两个不同的年份,对于每一年,我需要对从 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 的解决方案少一行 :)

  1. 使用 ymd 包的 lubridate 函数将字符类型转换为日期。
  2. 使用 DayMonth 函数仅考虑月和日所需的月日间隔
  3. year分组
  4. 过滤间隔
  5. 总结
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),从“日期”中获取 monthday,创建一个新日期将 ISOdateyear 标准化为单一年份(这里我们选择了 2021 - 可以是任何年份),然后我们使用 filter between 'newdate' 并指定leftright 参数作为自定义日期范围,然后按 'year' 进行分组并在 sum

中获取 'sales' 的 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 on Year 这是通过整数除法获得的,即 %/% 日期除以 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