【问题标题】:how to filter to one year ago from the most recent year R如何从最近一年R过滤到一年前
【发布时间】:2026-01-26 15:45:01
【问题描述】:

我有一个数据框如下:

B = data.frame(
  week = c("2021-08-09", "2021-11-11", "2017-06-18", "2020-09-07", "2020-09-07", "2020-09-07", "2020-09-12",
           "2020-08-23", "2019-12-22", "2017-10-29"),
  store = c(14071, 11468, 2428, 17777, 14821, 10935,  5127, 14772, 14772, 14772),
  fill = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1)
)

我正在尝试按最近两年内的日期进行过滤,因此在本例中为 2021 年和 2020 年。但是我并没有尝试明确硬编码 2021 年和 2020 年,因为当这些数据被刷新时,它将进入 2022 年和很快。例如,如果最近的两年是 2023 年和 2022 年,那么我想保留包含这些年份的日期的所有“周”值。本质上,我的目标是从当年(也就是 2 年的数据)中获取一年前的数据。根据我上面的例子,我试图得到的输出是:

B = data.frame(
  week = c("2021-08-09", "2021-11-11", "2020-09-07", "2020-09-07", "2020-09-07", "2020-09-12", "2020-08-23"),
  store = c(14071, 11468, 17777, 14821, 10935,  5127, 14772),
  fill = c(1, 1, 1, 1, 1, 1, 1)
)

知道如何以这种方式过滤吗?谢谢!

【问题讨论】:

    标签: r dataframe date sorting filter


    【解决方案1】:

    首先,看起来像日期的东西应该是真实的Date-class 对象,所以我会开始

    B$week <- as.Date(B$week)
    

    (不是严格要求,但无论如何可能是件好事。)

    从这里开始,

    oneyearago <- with(list(r = as.POSIXlt(max(B$week))), { r$year <- r$year - 1; r; })
    twoyears <- as.Date(format(oneyearago, format = "%Y-01-01"))
    B[B$week >= twoyears,]
    #         week store fill
    # 1 2021-08-09 14071    1
    # 2 2021-11-11 11468    1
    # 4 2020-09-07 17777    1
    # 5 2020-09-07 14821    1
    # 6 2020-09-07 10935    1
    # 7 2020-09-12  5127    1
    # 8 2020-08-23 14772    1
    

    【讨论】:

      【解决方案2】:

      这是一个基本的 R 方式。
      首先,将week 强制转换为"Date" 类。

      B$week <- as.Date(B$week)
      

      现在,使用format 获取年份向量,然后使用tail 排序并保留最后两个,最后过滤data.frame。

      yr <- as.integer(format(B$week, "%Y"))
      last_2 <- tail(sort(unique(yr)), n = 2)
      B[yr >= min(last_2), ]
      #        week store fill
      #1 2021-08-09 14071    1
      #2 2021-11-11 11468    1
      #3 2020-09-07 17777    1
      #4 2020-09-07 14821    1
      #5 2020-09-07 10935    1
      #6 2020-09-12  5127    1
      #7 2020-08-23 14772    1
      

      【讨论】:

        【解决方案3】:

        我们可以使用tidyverse

        library(dplyr)
        library(lubridate)
        B %>%
            mutate(year = year(ymd(week))) %>%
            arrange(desc(year)) %>% 
            filter(year >= min(head(unique(year), 2))) %>%
            select(-year)
        

        -输出

                week store fill
        1 2021-08-09 14071    1
        2 2021-11-11 11468    1
        3 2020-09-07 17777    1
        4 2020-09-07 14821    1
        5 2020-09-07 10935    1
        6 2020-09-12  5127    1
        7 2020-08-23 14772    1
        

        【讨论】:

          【解决方案4】:

          这是另一个使用辅助函数 get_year 的选项,它从日期返回年份值。

          get_year <- function(date) as.numeric(sub('-.*', '', date))
          
          subset(B, get_year(week) %in% (get_year(Sys.Date()) - 0:1))
          
          #        week store fill
          #1 2021-08-09 14071    1
          #2 2021-11-11 11468    1
          #4 2020-09-07 17777    1
          #5 2020-09-07 14821    1
          #6 2020-09-07 10935    1
          #7 2020-09-12  5127    1
          #8 2020-08-23 14772    1
          

          【讨论】:

            最近更新 更多