Recherchez la date la plus ancienne et la plus récente dans chaque ligne de R [dupliquer]

Dec 02 2020

J'ai un grand ensemble de données avec plus de 400 colonnes qui représentent certains éléments d'entrée utilisateur d'une plate-forme en ligne et l'heure à laquelle chaque entrée s'est produite. Chaque ligne représente un ID utilisateur.

200 de ces colonnes sont de la classe "POSIXct" "POSIXt" (par exemple, 2019-11-04 15:33:50), et des valeurs manquantes peuvent se produire, car tous les éléments ne sont pas affichés ou remplis par chaque utilisateur.

Mon objectif est de créer deux colonnes supplémentaires qui incluent la première et la dernière date par ligne de chacune de ces 200 colonnes "POSIXct" "POSIXt".

Voici un exemple simplifié du cadre et de l'une des colonnes supplémentaires souhaitées. (L'ID 4 serait quelqu'un qui n'a jamais pris la peine d'ouvrir le côté, mais qui dispose de données provenant d'autres sources de données et qui devrait rester dans l'ensemble de données pour le moment)

ID Other_columns    date_column          date_column2          date_column3             max_date (what I want)
1  "numeric"        2019-11-04 19:33:50  2019-11-05 15:33:50   2019-11-05 16:33:50      2019-11-05 16:33:50
2  "numeric"        NA                   2019-11-04 17:20:10   2019-11-09 19:12:50      2019-11-09 19:12:50
3  "numeric"        2019-11-07 20:33:50  NA                    2019-11-04 18:31:50      2019-11-07 20:33:50
4  NA               NA                   NA                    NA                       NA

Jusqu'à présent, je ne suis pas vraiment allé plus loin que le filtrage des autres colonnes sans date,

is.POSIXt <- function(x) inherits(x, "POSIXt")      
df%>%select(where(is.POSIXt))

Au lieu de sélectionner, je devrais probablement utiliser un mutate_at ou quelque chose comme condition, mais quel est le meilleur moyen de vérifier toutes ces 200 colonnes de date / heure restantes, puis d'affecter la date la plus ancienne / la plus récente aux colonnes nouvellement créées (tout en ignorant le NA valeurs).

Réponses

2 akrun Dec 02 2020 at 01:11

Nous pouvons utiliser pmaxet pminsur les colonnes «date» pour renvoyer la date la plus ancienne et la plus récente pour chaque ligne

library(dplyr)
 df %>%
     mutate(max_date = do.call(pmax, c(select(., starts_with('date')), na.rm = TRUE)),
            min_date = do.call(pmin, c(select(., starts_with('date')), 
         na.rm = TRUE)))
#  ID Other_columns         date_column        date_column2        date_column3            max_date            min_date
#1  1       numeric 2019-11-04 19:33:50 2019-11-05 15:33:50 2019-11-05 16:33:50 2019-11-05 16:33:50 2019-11-04 19:33:50
#2  2       numeric                <NA> 2019-11-04 17:20:10 2019-11-09 19:12:50 2019-11-09 19:12:50 2019-11-04 17:20:10
#3  3       numeric 2019-11-07 20:33:50                <NA> 2019-11-04 18:31:50 2019-11-07 20:33:50 2019-11-04 18:31:50
#4  4          <NA>                <NA>                <NA>                <NA>                <NA>                <NA>

Ou une autre option avec rowwiseavecc_across

df %>% 
   rowwise() %>% 
   mutate(max_date =  max(as.POSIXct(c_across(starts_with('date'))), 
         na.rm = TRUE),
          min_date = min(as.POSIXct(c_across(starts_with('date'))), 
         na.rm = TRUE))

-production

# A tibble: 4 x 7
# Rowwise: 
#     ID Other_columns date_column         date_column2        date_column3        max_date            min_date           
#  <int> <chr>         <chr>               <chr>               <chr>               <dttm>              <dttm>             
#1     1 numeric       2019-11-04 19:33:50 2019-11-05 15:33:50 2019-11-05 16:33:50 2019-11-05 16:33:50 2019-11-04 19:33:50
#2     2 numeric       <NA>                2019-11-04 17:20:10 2019-11-09 19:12:50 2019-11-09 19:12:50 2019-11-04 17:20:10
#3     3 numeric       2019-11-07 20:33:50 <NA>                2019-11-04 18:31:50 2019-11-07 20:33:50 2019-11-04 18:31:50
#4     4 <NA>          <NA>                <NA>                <NA>                NA NA               NA NA        

Les données

df <- structure(list(ID = 1:4, Other_columns = c("numeric", "numeric", 
"numeric", NA), date_column = c("2019-11-04 19:33:50", NA, "2019-11-07 20:33:50", 
NA), date_column2 = c("2019-11-05 15:33:50", "2019-11-04 17:20:10", 
NA, NA), date_column3 = c("2019-11-05 16:33:50", "2019-11-09 19:12:50", 
"2019-11-04 18:31:50", NA)), class = "data.frame", row.names = c(NA, 
-4L))



  
Neeraj Dec 02 2020 at 02:58

Voici une autre approche que vous pouvez utiliser sans utiliser de package.

Tout d'abord, obtenez des données pour les colonnes de date, et à partir de là, vous pouvez utiliser la applyfonction sur chaque ligne pour obtenir la valeur maximale et minimale en conséquence. Voici l'exemple:

df_date = df[, sapply(df, FUN = function(x) class(x)[1]) %in% c("POSIXct", "POSIXt")]
df$max = apply(df_date, 2, FUN = function(x) max(x, na.rm = TRUE) df$min = apply(df_date, 2, FUN = function(x) min(x, na.rm = TRUE)

Les données

structure(list(ID = 1:4, Other_columns = c("numeric", "numeric", 
"numeric", NA), date_column = structure(c(1572876230, NA, 1573139030, 
NA), class = c("POSIXct", "POSIXt"), tzone = ""), date_column2 = structure(c(1572948230, 
1572868210, NA, NA), class = c("POSIXct", "POSIXt"), tzone = ""), 
    date_column3 = structure(c(1572951830, 1573306970, 1572872510, 
    NA), class = c("POSIXct", "POSIXt"), tzone = "")), class = "data.frame", row.names = c(NA, 
-4L))