【问题标题】:Create events in weekly timeseries在每周时间序列中创建事件
【发布时间】:2021-04-24 15:59:30
【问题描述】:

我想创建一个包含两列的表。第一个代表工作周,在下面的示例中命名为 time_axis。 第二列也是代表一年中特定事件的日期序列,称为bank_holidays。每个日期都有一个值来表示它的存在。 我需要的是创建一个表,其中第一列时间轴保持不变,第二列将是一个和零的向量。在包含 bank_holiday 中的事件的周之外的任何地方都出现零,并且在包含 bank_holiday 中的这些日期的周中出现零。每周以 time_axis 中的日期开始

library(xts)
time_axis <- seq(as.Date("2017-01-21"), length = 10, by = "weeks")
bank_holidays <- as.Date(c("2017-02-01", "2017-02-13", "2017-02-18", "2018-03-18"))
bank_holidays <- as.xts(rep(1,4), order.by = bank_holidays)

期望的结果:

 df <- data.frame ( time_axis =  c("2017-01-20", "2017-01-27", "2017-02-03", "2017-02-10", "2017-02-17", "2017-02-24", "2017-03-03", "2017-03-10", "2017-03-17", "2017-03-24"), bank_holidays = c(0, 1, 0,1,1,0,0,0,1,0))
 df

关于如何制作它的任何想法? 谢谢。

需要牢记且数据不明显的一点:time_axis 上的星期从星期六开始。因此,2017-01-21 不是第 3 周的结束(如果这周从星期一开始),但已经是第 4 周了。

【问题讨论】:

    标签: r date time-series


    【解决方案1】:

    使用strftime"%V" 给出您可以匹配的 ISO 8601 周数。

    res <- data.frame(time_axis, 
                      bank_holidays =+(strftime(time_axis, "%V") %in%
                                         strftime(index(bank_holidays), "%V")))
    res
    #     time_axis bank_holidays
    # 1  2017-01-20             0
    # 2  2017-01-27             0
    # 3  2017-02-03             1
    # 4  2017-02-10             0
    # 5  2017-02-17             1
    # 6  2017-02-24             0
    # 7  2017-03-03             0
    # 8  2017-03-10             0
    # 9  2017-03-17             1
    # 10 2017-03-24             0
    

    编辑

    要使用开始在time_axis 变量中定义的自定义工作周,最简单的方法可能是比较bank_holidays 是否大于或等于该值。然后用colSums 计算TRUEs 给出设置为1 的索引。

    res <- data.frame(time_axis, bank_holidays=0)  ## init. column with `0`
    res$bank_holidays[colSums(sapply(index(bank_holidays), `>=`, time_axis))] <- 1  ## set matches to 1
    res
    #     time_axis bank_holidays
    # 1  2017-01-21             0
    # 2  2017-01-28             1
    # 3  2017-02-04             0
    # 4  2017-02-11             1
    # 5  2017-02-18             1
    # 6  2017-02-25             0
    # 7  2017-03-04             0
    # 8  2017-03-11             0
    # 9  2017-03-18             1
    # 10 2017-03-25             0
    

    【讨论】:

    • 感谢您的重播。只要一周从星期一开始,您给它的解决方案就可以工作。就我而言,这一周从星期六开始。因此,2017-01-21 已经是第四个工作周而不是第三个工作周。我已经更正了这个问题以反映这一点。关于如何改变这一点的任何线索?
    • @gogo88 我明白了,想出了另一个解决方案,请参阅编辑。
    • 这个解决方案正是我需要的。非常感谢
    【解决方案2】:

    这对我有用,比上一个答案长一点,但你可以看到这里发生了什么

    我需要开始日期和结束日期,因此我可以填写其间的其余日期,因此在您的示例中选择 11 周而不是 10 周。而且我还可以匹配银行假期的向量而不是 xts 对象

    library(xts)
    library(tidyverse)
    
    time_axis <- seq(as.Date("2017-01-20"), length = 11, by = "weeks") 
    bank_holidays <- as.Date(c("2017-02-01", "2017-02-13", "2017-02-18", "2018-03-18")) # I'll work with the vector 
    #bank_holidays <- as.xts(rep(1,4), order.by = bank_holidays)
    
    
    df <- tibble() # I'm creating an empty tibble
    for(i in 1:(length(time_axis)-1))  { # running a for loop for 10 weeks 
      
      df <- seq(as.Date(time_axis[i]), as.Date(time_axis[i+1]), "days") %>% # filling the dates between the two dates
        enframe(name = NULL) %>% #converting it into a data frame (tibble)
        mutate(week = as.Date(time_axis[i])) %>% # creating a new column indicating which week the given date belong to
        bind_rows(df) # binding the rows to previous dataframe
    }
    

    现在我正在使用 df 并检查给定的假期是否与我们生成的日期匹配。如果存在,则为 1,否则将为 0。 然后我是 group_by 基于周列,这是我们上面给定的周,并总结以找到总和

    df %>% 
      mutate(bank_holidays_presence = if_else(value %in% bank_holidays, 1, 0)) %>% 
      group_by(week) %>% 
      summarise(sum = bank_holidays_presence %>% sum())
    
    # A tibble: 10 x 2
    #  week         sum
    #   <date>     <dbl>
    # 1 2017-01-20     0
    # 2 2017-01-27     1
    # 3 2017-02-03     0
    # 4 2017-02-10     1
    # 5 2017-02-17     1
    # 6 2017-02-24     0
    # 7 2017-03-03     0
    # 8 2017-03-10     0
    # 9 2017-03-17     0
    #10 2017-03-24     0
    

    这种方法的优点是,即使您在某一周有多个假期,它也会给出计数,而不仅仅是存在或不存在

    【讨论】:

      猜你喜欢
      • 2023-01-12
      • 2012-06-10
      • 1970-01-01
      • 2016-09-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多