2016-12-05 78 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

通過連續你的意思是隻有第二天是前一個+的日子?星期五之後是星期六還是星期五?或者,也許你只關心獨特日子的數量? –