2016-12-05 40 views
2

我有一个数据帧如下:记录连续几天通过集团中的R

DATE <- as.Date(c('2016-12-01', '2016-12-02', '2016-12-03', '2016-12-04', '2016-12-01', '2016-12-03', '2016-12-04', '2016-12-04')) 
Parent <- c('A','A','A','A','A','A','A','B') 
Child <- c('ab', 'ab', 'ab', 'ab', 'ac','ac', 'ac','bd') 
salary <- c(1000, 100, 4000, 2000,1000,3455,1234,600) 
avg_child_salary <- c(500, 500, 500, 500, 300, 300, 300, 9000) 
Callout <- c('HIGH', 'LOW', 'HIGH', 'HIGH', 'HIGH', 'HIGH', 'HIGH', 'LOW') 
employ.data <- data.frame(DATE, Parent, Child, avg_child_salary, salary, Callout) 

employ.data 

     DATE Parent Child avg_child_salary salary Callout 
1 2016-12-01  A ab    500 1000 HIGH 
2 2016-12-02  A ab    500 100  LOW 
3 2016-12-03  A ab    500 4000 HIGH 
4 2016-12-04  A ab    500 2000 HIGH 
5 2016-12-01  A ac    300 1000 HIGH 
6 2016-12-03  A ac    300 3455 HIGH 
7 2016-12-04  A ac    300 1234 HIGH 
8 2016-12-04  B bd    9000 600  LOW 

我过滤掉了就在昨天的数据是2016-12-04如下:

yesterday <- as.Date(Sys.Date()-1) 
df2<-filter(employ.data, DATE == yesterday) 
df2 

      DATE Parent Child avg_child_salary salary Callout 
    4 2016-12-04  A ab    500 2000 HIGH 
    7 2016-12-04  A ac    300 1234 HIGH 
    8 2016-12-04  B bd    9000 600  LOW 

我的目标是包括列Callout显示从2016-12-04连续天的数额,标注已HIGHLOWChild根据employ.data数据帧。这是我需要的最终输出:

  DATE Parent Child avg_child_salary salary Callout Consec. Days with Callout 
    4 2016-12-04  A ab    500 2000 HIGH       2 
    7 2016-12-04  A ac    300 1234 HIGH       2 
    8 2016-12-04  B bd    9000 600  LOW       1 

谢谢!

回答

1

这里是另一种方法那是相当混乱,但我觉得你想要做什么:

library(dplyr) 
yesterday <- as.Date(Sys.Date()-1) 
df2 <- employ.data %>% group_by(Child) %>% 
    mutate(`Consec. Days with Callout`=cumsum(rev(cumprod(rev((yesterday-DATE)==(which(DATE == yesterday)-row_number()) & Callout==Callout[DATE == yesterday]))))) %>% 
    filter(DATE == yesterday) 
##Source: local data frame [3 x 7] 
##Groups: Child [3] 
## 
##  DATE Parent Child avg_child_salary salary Callout Consec. Days with Callout 
##  <date> <fctr> <fctr>   <dbl> <dbl> <fctr>      <dbl> 
##1 2016-12-04  A  ab    500 2000 HIGH       2 
##2 2016-12-04  A  ac    300 1234 HIGH       2 
##3 2016-12-04  B  bd    9000 600  LOW       1 

注:

  1. (yesterday-DATE)==(which(DATE == yesterday)-row_number()) & Callout==Callout[DATE == yesterday]计算出如果Callout为t,则该行的条件将为TRUE他与Calloutyesterday相同,并且与行yesterday的行距离与日期的距离相同。这给了Cond列如下图所示:

    Source: local data frame [8 x 7] 
    Groups: Child [3] 
    
         DATE Parent Child avg_child_salary salary Callout Cond 
         <date> <fctr> <fctr>   <dbl> <dbl> <fctr> <lgl> 
    1 2016-12-01  A  ab    500 1000 HIGH TRUE 
    2 2016-12-02  A  ab    500 100  LOW FALSE 
    3 2016-12-03  A  ab    500 4000 HIGH TRUE 
    4 2016-12-04  A  ab    500 2000 HIGH TRUE 
    5 2016-12-01  A  ac    300 1000 HIGH FALSE 
    6 2016-12-03  A  ac    300 3455 HIGH TRUE 
    7 2016-12-04  A  ac    300 1234 HIGH TRUE 
    8 2016-12-04  B  bd    9000 600  LOW TRUE 
    
  2. 有鉴于此,我们希望从为yesterday(由Child分组)排倒数的连续TRUE数量。为此,我们可以使用rev来反转矢量,做一个cumprod,一旦它遇到FALSE就会从1切换到0,使用rev再次反转矢量,最后做cumsum累积连续的天数。这样做可以使其中Consec. Days with Callout列被解释为以前的连续天数与同Calloutyesterday如下:

    Source: local data frame [8 x 7] 
    Groups: Child [3] 
    
         DATE Parent Child avg_child_salary salary Callout Consec. Days with Callout 
         <date> <fctr> <fctr>   <dbl> <dbl> <fctr>      <dbl> 
    1 2016-12-01  A  ab    500 1000 HIGH       0 
    2 2016-12-02  A  ab    500 100  LOW       0 
    3 2016-12-03  A  ab    500 4000 HIGH       1 
    4 2016-12-04  A  ab    500 2000 HIGH       2 
    5 2016-12-01  A  ac    300 1000 HIGH       0 
    6 2016-12-03  A  ac    300 3455 HIGH       1 
    7 2016-12-04  A  ac    300 1234 HIGH       2 
    8 2016-12-04  B  bd    9000 600  LOW       1 
    
  3. 最后,做filter像你一样,产生最终结果。

+0

你对这个问题有什么问题吗?如果是这样,请在这里留言。否则,我不会直接收到它们。 – aichao

+0

我相信你会得到那个错误,因为你有一个没有日期匹配“昨天”的组。真的吗? – aichao

2

试试这个我的男人

library(lubridate) 

df3 <- df2 %>% 
     group_by(child, callout) %>%       
     mutate(DATE = ymd(DATE), 
       consecutive_day_flag = if_else(DATE == (lag(DATE) + days(1)), 1, 0), 
       how_many = sum(consecutive_day_flag)) 
+0

这真的很好谢谢。唯一的是Consec。带有标注的日期与我在顶部的数字不符。我猜测它已经不包括2016-12-04了。它必须引用employ.data数据框。让我知道这是否合理,并感谢您的帮助! –

+0

我很抱歉没有在问题中说清楚,只是修改了问题。 @Noobie –

+0

通过连续你的意思是只有第二天是前一个+的日子?星期五之后是星期六还是星期五?或者,也许你只关心独特日子的数量? –