Finden Sie das früheste und späteste Datum in jeder Zeile in R [Duplikat]
Ich habe einen großen Datensatz mit über 400 Spalten, die bestimmte Benutzereingabeelemente von einer Online-Plattform und den Zeitpunkt darstellen, zu dem jede Eingabe erfolgte. Jede Zeile repräsentiert eine Benutzer-ID.
200 dieser Spalten gehören zur Klasse "POSIXct" "POSIXt" (z. B. 2019-11-04 15:33:50), und es können fehlende Werte auftreten, da nicht jedes Element jedem Benutzer angezeigt oder von diesem ausgefüllt wird.
Mein Ziel ist es, zwei zusätzliche Spalten zu erstellen, die das früheste und das späteste Datum pro Zeile jeder dieser 200 "POSIXct" "POSIXt" -Spalten enthalten.
Hier ein vereinfachtes Beispiel des Rahmens und einer der gewünschten zusätzlichen Spalten. (ID 4 wäre jemand, der sich nie die Mühe gemacht hat, die Seite zu öffnen, aber Daten aus anderen Datenquellen zur Verfügung hat und vorerst im Datensatz bleiben sollte.)
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
Bisher bin ich nicht weiter gekommen, als die anderen Spalten ohne Datum herauszufiltern.
is.POSIXt <- function(x) inherits(x, "POSIXt")
df%>%select(where(is.POSIXt))
Anstelle der Auswahl sollte ich wahrscheinlich ein mutate_at oder etwas als Bedingung verwenden, aber was ist der beste Weg, um alle verbleibenden 200 Datums- / Zeitspalten zu überprüfen und dann den neu erstellten Spalten das früheste / späteste Datum zuzuweisen (während die NA ignoriert wird Werte).
Antworten
Wir können pmax
und pmin
in den 'Datum'-Spalten verwenden, um das früheste und späteste Datum für jede Zeile zurückzugeben
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>
Oder eine andere Option mit rowwise
mitc_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))
-Ausgabe
# 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
Daten
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))
Hier ist ein weiterer Ansatz, den Sie ohne Verwendung eines Pakets verwenden können.
Holen Sie sich zunächst Daten für Datumsspalten, und verwenden Sie die apply
Funktion für jede Zeile, um den Max- und Min-Wert entsprechend abzurufen. Hier ist das Beispiel:
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)
Daten
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))