Finden Sie das früheste und späteste Datum in jeder Zeile in R [Duplikat]

Dec 02 2020

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

2 akrun Dec 02 2020 at 01:11

Wir können pmaxund pminin 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 rowwisemitc_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))



  
Neeraj Dec 02 2020 at 02:58

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 applyFunktion 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))