计算日期范围与范围之间每周的天数之间的周数

时间:2018-03-19 12:25:21

标签: r dplyr

输入数据框

   ID   RID PID check_in         check_out
10240   1   1   13-08-2014 9.30  14-08-2014 9.30
10240   2   1   16-08-2014 9.30  17-08-2014 9.30
10240   3   2   18-09-2012 9.30  25-09-2012 9.30
10240   4   1   25-09-2012 9.30  30-09-2012 9.30
10240   5   1   27-01-2015 22.30 27-02-2015 20.30

期待输出

  ID    RID PID check_in               check_out     Weekite Weekstart  Weekgrp Days
10240   1   1   13-08-2014 9.30      14-08-2014 9.30    1   10-08-2014  10-08-2014  1
10240   2   1   16-08-2014 9.30      17-08-2014 9.30    1   10-08-2014  10-08-2014  1
10240   3   2   18-09-2012 9.30      25-09-2012 9.30    1   16-09-2012  16-09-2012  7
10240   4   1   25-09-2012 9.30      30-09-2012 9.30    1   23-09-2012  23-09-2012  5
10240   5   1   27-01-2015 22.30    27-02-2015 20.30    5   25-01-2015  25-01-2015  5
10240   5   1   27-01-2015 22.30    27-02-2015 20.30    5   25-01-2015  01-02-2015  7
10240   5   1   27-01-2015 22.30    27-02-2015 20.30    5   25-01-2015  08-02-2015  7
10240   5   1   27-01-2015 22.30    27-02-2015 20.30    5   25-01-2015  15-02-2015  7
10240   5   1   27-01-2015 22.30    27-02-2015 20.30    5   25-01-2015  22-02-2015  5

但是我没有按预期获得输出。

以下是我的代码:

output_df <- weektest %>% 
  group_by(ID, RID,PID) %>%
  mutate(Weekite = ceiling(difftime(strptime(check_out, format = "%Y-%m-%d"),
                            strptime(check_in, format = "%Y-%m-%d"),units="weeks"))) %>%
  mutate(Weekstart = as.Date(cut(check_in,
                                 breaks = "week",
                                 start.on.monday = FALSE))) %>%

  mutate(Weekgrp = list(seq(Weekstart[1], by="week", length.out=Weekite[1]))) %>%
  unnest %>%

  mutate(Days = if(n() > 1)
                       case_when(

                         row_number() == 1L ~ day(Weekgrp[2]) - day(check_in),
                         row_number() == n() ~ day(check_out) - day(Weekgrp[n()]),
                         row_number() != 1L | n() ~ day(Weekgrp[n()]) - day(Weekgrp[n()-1]),
                         )
              else day(check_out)- day(check_in)

  )

row_number() == 1L ~ day(Weekgrp[2]) - day(check_in)提供的Days不正确-26

请帮忙。

1 个答案:

答案 0 :(得分:0)

这是可能的解决方案之一:

output_df <- weektest %>% 
  group_by(ID, RID,PID) %>%
  mutate(Weekstart = as.Date(cut(check_in,
                                 breaks = "week",
                                 start.on.monday = FALSE))) %>% 
  mutate(Weekite = ceil(difftime(strptime(check_out, format = "%Y-%m-%d"),
                                 strptime(Weekstart, format = "%Y-%m-%d"),units="weeks"))) %>%  
  mutate(Weekgrp = list(seq(Weekstart[1], by="week", length.out=Weekite[1]))) %>%
  unnest %>%  
  mutate(Days = if(n() > 1)
    case_when(
      row_number() == 1L ~ as.numeric(Weekgrp[2] - as.Date(strptime(check_in,format = "%Y-%m-%d"))),
      row_number() == n() ~ as.numeric(as.Date(strptime(check_out,format = "%Y-%m-%d")) - Weekgrp[n()]),
      row_number() != 1L | n() ~ as.numeric(Weekgrp[n()] - Weekgrp[n()-1])
    )
    else as.numeric(as.Date(strptime(check_out,format = "%Y-%m-%d"))- as.Date(strptime(check_in,format = "%Y-%m-%d")))    
  )  
output_df$Weekite <- NULL
output_df$Weekstart <- NULL

output_df <- weektest %>% group_by(ID, RID,PID) %>% mutate(Weekstart = as.Date(cut(check_in, breaks = "week", start.on.monday = FALSE))) %>% mutate(Weekite = ceil(difftime(strptime(check_out, format = "%Y-%m-%d"), strptime(Weekstart, format = "%Y-%m-%d"),units="weeks"))) %>% mutate(Weekgrp = list(seq(Weekstart[1], by="week", length.out=Weekite[1]))) %>% unnest %>% mutate(Days = if(n() > 1) case_when( row_number() == 1L ~ as.numeric(Weekgrp[2] - as.Date(strptime(check_in,format = "%Y-%m-%d"))), row_number() == n() ~ as.numeric(as.Date(strptime(check_out,format = "%Y-%m-%d")) - Weekgrp[n()]), row_number() != 1L | n() ~ as.numeric(Weekgrp[n()] - Weekgrp[n()-1]) ) else as.numeric(as.Date(strptime(check_out,format = "%Y-%m-%d"))- as.Date(strptime(check_in,format = "%Y-%m-%d"))) ) output_df$Weekite <- NULL output_df$Weekstart <- NULL