3 votes

Comment puis-je trouver la date la plus proche d'une autre date dans une colonne différente lors d'un regroupement par ID en utilisant R ?

Je cherche une méthode pour examiner chaque date dans "Date A" et trouver la date la plus proche après cette valeur dans "Date B" par ID (group_by). Je souhaite ensuite calculer la différence en jours. Voici le tableau que je souhaite obtenir.

ID    |  Date A    |  Date B     | Difference| 
11111 |  09/01/21  |  09/03/21   | 2         |
22222 |  09/06/21  |  09/20/21   | 11        | 
11111 |  09/08/21  |  09/18/21   | 10        |  
44444 |  09/04/21  |  NA         | 11        | 
44444 |  09/10/21  |  09/15/21   | 5         |
22222 |  NA        |  09/17/21   | NA        | 
77777 |  NA        |  10/16/21   | NA        |
77777 |  09/04/21  |  10/17/21   | 24        |
77777 |  09/01/21  |  09/28/21   | 27        |

Si vous pouviez m'aider à résoudre ce problème, je vous en serais très reconnaissant !

Santé

1voto

jmuhlenkamp Points 1412

A dplyr solution via group_by La solution n'est pas évidente pour moi ici, mais voici une solution relativement simple. sqldf solution. On peut supposer que cela pourrait se traduire par une dplyr solution si vous le souhaitez vraiment.

Commencez par simuler les données dans R

df <- dplyr::tribble(
  ~'ID', ~'Date A', ~'Date B',
  11111,  '09/01/21', '09/03/21',
  22222,  '09/06/21', '09/20/21',
  11111,  '09/08/21', '09/18/21',
  44444,  '09/04/21', NA        ,
  44444,  '09/10/21', '09/15/21',
  22222,  NA        , '09/17/21',
  77777,  NA        , '10/16/21',
  77777,  '09/04/21', '10/17/21',
  77777,  '09/01/21', '09/28/21'
)
df$`Date A` <- lubridate::mdy(df$`Date A`)
df$`Date B` <- lubridate::mdy(df$`Date B`)
df

Ce qui ressemble à

# A tibble: 9 x 3
     ID `Date A`   `Date B`  
  <dbl> <date>     <date>    
1 11111 2021-09-01 2021-09-03
2 22222 2021-09-06 2021-09-20
3 11111 2021-09-08 2021-09-18
4 44444 2021-09-04 NA        
5 44444 2021-09-10 2021-09-15
6 22222 NA         2021-09-17
7 77777 NA         2021-10-16
8 77777 2021-09-04 2021-10-17
9 77777 2021-09-01 2021-09-28

Effectuez ensuite une jointure d'inégalité combinée à un groupe par. La colonne I est ajoutée pour tenir compte des nuances des données, telles que les multiples de la même date A au sein de chaque ID.

df$I <- 1:nrow(df)

df <- sqldf::sqldf('
SELECT a.I, a.ID, a."Date A", a."Date B",
  MIN(b."Date B") AS NextB
FROM df a
LEFT JOIN df b
  ON a.ID = b.ID
  AND a."Date A" < b."Date B"
GROUP BY a.I, a.ID, a."Date A", a."Date B"
ORDER BY a.I
')

df$Difference = df$NextB - as.integer(df$`Date A`)
df$I <- NULL
df$NextB <- NULL
df

Ce qui correspond à vos données d'exemple (et devrait permettre une bonne généralisation pour les cas limites qui ne figurent pas dans vos données d'exemple). Il n'est pas certain qu'il soit possible de l'adapter à des données non triviales.

     ID     Date A     Date B Difference
1 11111 2021-09-01 2021-09-03          2
2 22222 2021-09-06 2021-09-20         11
3 11111 2021-09-08 2021-09-18         10
4 44444 2021-09-04       <NA>         11
5 44444 2021-09-10 2021-09-15          5
6 22222       <NA> 2021-09-17         NA
7 77777       <NA> 2021-10-16         NA
8 77777 2021-09-04 2021-10-17         24
9 77777 2021-09-01 2021-09-28         27

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X