Recherchez la date la plus ancienne et la plus récente dans chaque ligne de R [dupliquer]
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
Nous pouvons utiliser pmax
et pmin
sur 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 rowwise
avecc_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))
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 apply
fonction 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))