簡體   English   中英

在R中按組記錄連續天數

[英]Record Consecutive Days by Group in 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

謝謝!

試試這個我的男人

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))

這是另一種相當混亂的方法,但我認為您想要做的是:

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]計算,這將是一個條件TRUE的行,如果Callout相同的Callout對於yesterday和若從在排排的距離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 Consec. Days with Callout列被解釋為與yesterday具有相同Callout的前連續天數:

     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以生成最終結果。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM