【问题标题】:add incrimental dates in a dataframe by the condition in R通过 R 中的条件在数据框中添加增量日期
【发布时间】:2017-02-11 23:36:10
【问题描述】:

干杯,我有一个具有以下结构的数据框。 Week_Start_Date 是一周的开始日期(星期日)。

DF1:
Week_Start_Date     Event              Days
2016-08-14          Independence       4
2016-01-24          Republic           3

我想更改 DF1(将日期增加一天,直到 Days 列)。例如:从 2016 年 8 月 14 日(Week_Start_Date)到 2016 年 8 月 17 日,庆祝独立 4 天。

DF2:
Week_Start_Date     Event             Days
2016-08-14          Independence      1
2016-08-15          Independence      2
2016-08-16          Independence      3
2016-08-14          Independence      4
2016-01-24          Republic          1
2016-01-25          Republic          2
2016-01-26          Republic          3

我正在使用“dplyr”包,但我尝试过,但没有成功:

DF2 <- rbind(DF1, DF1 %>% 
mutate(Week_Start_Date = Week_Start_Date + 1:Days, Event=Event, Days = 1:Days))

谁能指出我正确的方向?

注意:

str(DF1$Week_Start_Date): Date, format: "2016-08-04"

【问题讨论】:

    标签: r datetime dataframe dplyr


    【解决方案1】:

    如果您的Event 列不包含重复值,您可以使用dplyrtidyr 包:

    library(dplyr)
    library(tidyr)
    df %>% 
           group_by(Event, Week_Start_Date) %>% 
           complete(Days = sequence(Days)) %>% 
           ungroup() %>% 
           mutate(Week_Start_Date = Week_Start_Date + Days - 1)
    
    # A tibble: 7 x 3
    #         Event Week_Start_Date  Days
    #         <chr>          <date> <int>
    #1 Independence      2016-08-14     1
    #2 Independence      2016-08-15     2
    #3 Independence      2016-08-16     3
    #4 Independence      2016-08-17     4
    #5     Republic      2016-01-24     1
    #6     Republic      2016-01-25     2
    #7     Republic      2016-01-26     3
    

    更一般地,如果Event 列包含重复值,您可以创建一个行号作为组变量,这可以通过tibble::rownames_to_column() 函数完成。

    【讨论】:

      【解决方案2】:

      基础 R 中的解决方案:

      # Sample data
      DF1 <- cbind.data.frame(
          Week_Start_Date = c(as.Date("2016-08-14"), as.Date("2016-01-24")),
          Event = c("Independence", "Republic"),
          Days = c(4,3),
          stringsAsFactors = FALSE);
      
      # Apply per row, create list and rbind entries
      lst <- apply(DF1, 1, function(x) 
          cbind.data.frame(
              Week_Start_Date = as.Date(x["Week_Start_Date"]) + seq(0, as.numeric(x["Days"]) - 1),
              Event = x["Event"],
              Days = seq(1, as.numeric(x["Days"])),
              row.names = NULL));
      df <- do.call(rbind, lst);
      
      # Output
      print(df);
        Week_Start_Date        Event Days
      1      2016-08-14 Independence    1
      2      2016-08-15 Independence    2
      3      2016-08-16 Independence    3
      4      2016-08-17 Independence    4
      5      2016-01-24     Republic    1
      6      2016-01-25     Republic    2
      7      2016-01-26     Republic    3
      

      【讨论】:

        【解决方案3】:

        这是一个使用 data.table 的选项,在根据 'Days' 中的值扩展行后

        library(data.table)
        setDT(df1[rep(seq_len(nrow(df1)), df1$Days),])[,
           .(Week_Start_Date = Week_Start_Date + seq(.N)-1, Days = seq_len(.N)) , by = Event]
        #          Event Week_Start_Date Days
        #1: Independence      2016-08-14    1
        #2: Independence      2016-08-15    2
        #3: Independence      2016-08-16    3
        #4: Independence      2016-08-17    4
        #5:     Republic      2016-01-24    1
        #6:     Republic      2016-01-25    2
        #7:     Republic      2016-01-26    3
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-02-17
          • 1970-01-01
          • 2018-01-31
          • 1970-01-01
          • 2022-06-15
          • 2021-03-04
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多