Oi Fe, tudo bem?
Me parece que para a maior parte dos casos dá pra resolver usando uma conta de maior data menos menor data (quando são os casos 1, 3 e 4 que você citou). Eu entendi certo?
O que nao resolve assim é o caso 2 (intervalos diferentes, entao calcular a diferença para cada linha nesses ids, e somar as diferenças).
eu pensei em : identificar onde é o caso 2, separar a base, e fazer a “conta” separado (pensando na regra que vale pra cada um)
aqui vai um primeiro brainstorm. não está elegante o código… acho que podemos pensar em como melhorar. também seria bom testar para mais dados e verificar se dá certo.
library(magrittr, include.only = "%>%")
# criar a base
# vc comentou comigo que as vezes chega a ter 4 casos.
# adicionei mais uma linha no id 3
banco_teste_datas <- tibble::tribble(
~Id, ~Data_Inicio, ~Data_Final,
1L, "17/06/2020", "28/06/2020",
1L, "02/07/2020", "24/07/2020",
2L, "14/08/2020", "01/09/2020",
2L, "05/08/2020", "14/08/2020",
3L, "24/05/2020", "28/05/2020",
3L, "17/05/2020", "24/05/2020",
3L, "08/05/2020", "17/05/2020",
3L, "08/05/2020", "17/05/2020", # aqui dupliquei uma linha para ter 4 casos
4L, "30/08/2020", "09/09/2020",
4L, "24/08/2020", "13/09/2020",
5L, "04/12/2020", "18/12/2020",
5L, "04/12/2020", "18/12/2020"
)
# olhar a base
dplyr::glimpse(banco_teste_datas)
#> Rows: 12
#> Columns: 3
#> $ Id <int> 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5
#> $ Data_Inicio <chr> "17/06/2020", "02/07/2020", "14/08/2020", "05/08/2020", "2…
#> $ Data_Final <chr> "28/06/2020", "24/07/2020", "01/09/2020", "14/08/2020", "2…
# arrumar as colunas
df <- banco_teste_datas %>%
janitor::clean_names() %>%
dplyr::mutate(
data_inicio = readr::parse_date(data_inicio, format = "%d/%m/%Y"),
data_final = readr::parse_date(data_final, format = "%d/%m/%Y")
)
# aqui basicamente eu to tentando testar o que cai no caso 2!
teste_casos <- df %>%
dplyr::mutate(intervalo = lubridate::interval(data_inicio, data_final)) %>%
dplyr::select(-data_inicio, -data_final) %>%
dplyr::group_by(id) %>%
dplyr::mutate(ordem = dplyr::row_number()) %>%
dplyr::ungroup() %>%
tidyr::pivot_wider(
id_cols = id,
values_from = intervalo,
names_from = ordem,
names_prefix = "ordem_"
) %>%
dplyr::mutate(
overlap_1_2 = lubridate::int_overlaps(ordem_1, ordem_2),
overlap_1_3 = lubridate::int_overlaps(ordem_1, ordem_3),
overlap_1_4 = lubridate::int_overlaps(ordem_1, ordem_4),
overlap_2_3 = lubridate::int_overlaps(ordem_2, ordem_3),
overlap_2_4 = lubridate::int_overlaps(ordem_2, ordem_4),
overlap_3_4 = lubridate::int_overlaps(ordem_3, ordem_4)
) %>%
dplyr::mutate_at(
dplyr::vars(overlap_1_2:overlap_3_4),
~ tidyr::replace_na(., 0)
) %>%
dplyr::mutate(soma_overlap = overlap_1_2 + overlap_1_3 + overlap_1_4 + overlap_2_3 +
overlap_2_4 + overlap_3_4)
# aqui quando a soma_overlap = 0 , é o caso 2.
# separar os IDs de cada caso
ids_caso_2 <-
teste_casos %>%
dplyr::filter(soma_overlap == 0) %>%
dplyr::pull(id)
ids_outros_casos <-
teste_casos %>%
dplyr::filter(soma_overlap != 0) %>%
dplyr::pull(id)
# calcular a diferenca para outros casos
diferenca_outros_casos <- df %>%
dplyr::filter(id %in% ids_outros_casos) %>%
tibble::rowid_to_column(var = "numero_linha") %>%
tidyr::pivot_longer(
names_to = "tipo_data",
cols = c(data_inicio, data_final)
) %>%
dplyr::group_by(id) %>%
dplyr::filter(value == min(value) | value == max(value)) %>%
dplyr::ungroup() %>%
dplyr::distinct(id, tipo_data, value) %>%
tidyr::pivot_wider(
id_cols = id,
names_from = tipo_data,
values_from = value
) %>%
dplyr::mutate(diferenca = data_final - data_inicio) %>%
dplyr::select(id, diferenca)
diferenca_caso_2 <- df %>%
dplyr::filter(id %in% ids_caso_2) %>%
dplyr::mutate(diferenca = data_final - data_inicio) %>%
dplyr::group_by(id) %>%
dplyr::summarise(diferenca = sum(diferenca, na.rm = TRUE))
# juntar tudo na base
resposta <-
dplyr::bind_rows(diferenca_outros_casos, diferenca_caso_2) %>%
dplyr::arrange(id)
# o que queremos no final? um df com id e coluna com o valor calculado
resposta %>% knitr::kable()
id |
diferenca |
1 |
33 days |
2 |
27 days |
3 |
20 days |
4 |
20 days |
5 |
14 days |
Created on 2021-06-02 by the reprex package (v2.0.0.9000)