Начиная с даты начала и окончания, получите номер на каждую дату - PullRequest
0 голосов
/ 06 ноября 2019

Я хочу узнать количество людей в организации. У меня есть Дата, когда каждый из них начал и закончил свою работу там.

Я хотел бы сделать это с помощью R и, если возможно, с использованием подхода tidyverse

Пример:

Person Start End
John 01/01/1990 01/07/1992
Eve  12/27/1991 12/31/1992

Это должно дать:

Date People
12/31/1989 0
01/01/1990 1
01/02/1990 1
...
12/27/1991 2
12/38/1991 2
...
01/07/1992 2
01/08/1992 1
...
12/31/1992 1
01/01/1993 0

Ответы [ 3 ]

2 голосов
/ 06 ноября 2019

Используя tidyverse, мы можем создать последовательность между Start и End для каждого Person и count числа Date.

library(tidyverse)

df %>%
  mutate_at(-1,lubridate::mdy) %>%
  mutate(Date = map2(Start, End, seq, by = "1 day")) %>%
  unnest(Date) %>%
  count(Date)


# A tibble: 1,096 x 2
#   Date           n
#   <date>     <int>
# 1 1990-01-01     1
# 2 1990-01-02     1
# 3 1990-01-03     1
# 4 1990-01-04     1
# 5 1990-01-05     1
# 6 1990-01-06     1
# 7 1990-01-07     1
# 8 1990-01-08     1
# 9 1990-01-09     1
#10 1990-01-10     1
# … with 1,086 more rows

данных

df <- structure(list(Person = structure(2:1, .Label = c("Eve", "John"
), class = "factor"), Start = structure(1:2, .Label = c("01/01/1990", 
"12/27/1991"), class = "factor"), End = structure(1:2, .Label = c("01/07/1992", 
"12/31/1992"), class = "factor")), class = "data.frame", row.names = c(NA, -2L))
0 голосов
/ 06 ноября 2019
library(dplyr)
library(lubridate)
df %>% 
    rowwise() %>% 
    mutate(Date= toString(seq.Date(mdy(Start), mdy(End), by=1))) %>% 
    separate_rows(Date, sep=',') %>% 
    mutate(Date=ymd(Date)) %>% 
    right_join(data.frame(Date=seq.Date(mdy('12/31/1989'), mdy('01/01/1993'),1))) %>% 
    group_by(Date) %>% 
    summarise(People=sum(!is.na(End)))

# A tibble: 1,098 x 2
   Date       People
   <date>      <int>
 1 1989-12-31      0
 2 1990-01-01      1
 3 1990-01-02      1
 4 1990-01-03      1
 5 1990-01-04      1
 6 1990-01-05      1
 7 1990-01-06      1
 8 1990-01-07      1
 9 1990-01-08      1
10 1990-01-09      1
# ... with 1,088 more rows
0 голосов
/ 06 ноября 2019

Вот метод, использующий data.table::foverlaps()

#load libraries
library(data.table)
library(lubridate)

#create sample data
DT <- fread("Person Start End
John 01/01/1990 01/07/1992
Eve  12/27/1991 12/31/1992")
#set dates as POSIXct timestamps
DT[, `:=`( Start = as.POSIXct( Start, format = "%m/%d/%Y", tz = "UTC" ),
           End   = as.POSIXct( End, format = "%m/%d/%Y", tz = "UTC" ) ) ]

#create table with all days in periods from DT
DT.dates <- data.table( from = seq( min( DT$Start ), max( DT$End ), by = "1 day" ) )
DT.dates[, to := from %m+% days(1) - 1 ]

#set keys
setkey( DT, Start, End )
setkey( DT.dates, from, to )

#perform overlap join and summarise
ans <- foverlaps( DT, DT.dates )[, .(People = uniqueN( Person ) ), by = (Date = from)]

выход

ans[720:740,]
#           Date People
#  1: 1991-12-21      1
#  2: 1991-12-22      1
#  3: 1991-12-23      1
#  4: 1991-12-24      1
#  5: 1991-12-25      1
#  6: 1991-12-26      1
#  7: 1991-12-27      2
#  8: 1991-12-28      2
#  9: 1991-12-29      2
# 10: 1991-12-30      2
# 11: 1991-12-31      2
# 12: 1992-01-01      2
# 13: 1992-01-02      2
# 14: 1992-01-03      2
# 15: 1992-01-04      2
# 16: 1992-01-05      2
# 17: 1992-01-06      2
# 18: 1992-01-07      2
# 19: 1992-01-08      1
# 20: 1992-01-09      1
# 21: 1992-01-10      1
#           Date People
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...