Temukan tanggal paling awal dan terbaru dalam setiap baris di R [duplikat]

Dec 02 2020

Saya memiliki kumpulan data besar dengan lebih dari 400 kolom yang mewakili elemen input pengguna tertentu dari platform online dan waktu setiap input terjadi. Setiap baris mewakili ID pengguna.

200 dari kolom tersebut adalah dari kelas "POSIXct" "POSIXt" (mis. 2019-11-04 15:33:50), dan nilai yang hilang dapat terjadi, karena tidak setiap elemen ditampilkan atau diisi oleh setiap pengguna.

Sasaran saya adalah membuat dua kolom tambahan yang menyertakan tanggal paling awal dan terbaru per baris dari masing-masing 200 kolom "POSIXct" "POSIXt" tersebut.

Di sini contoh sederhana dari bingkai dan salah satu kolom tambahan yang diinginkan. (ID 4 akan menjadi seseorang yang tidak pernah repot-repot membuka sisi, tetapi memiliki data dari sumber data lain yang tersedia, dan harus tetap dalam dataset untuk saat ini)

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

Sejauh ini saya tidak melangkah lebih jauh yang memfilter kolom non-tanggal lainnya,

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

Alih-alih memilih, saya mungkin harus menggunakan mutate_at atau sesuatu sebagai kondisi, tetapi apa cara terbaik untuk memeriksa semua 200 kolom tanggal / waktu yang tersisa dan kemudian menetapkan tanggal paling awal / terbaru ke kolom yang baru dibuat (sambil mengabaikan NA nilai).

Jawaban

2 akrun Dec 02 2020 at 01:11

Kita dapat menggunakan pmaxdan pminpada kolom 'tanggal' untuk mengembalikan tanggal paling awal dan terbaru untuk setiap baris

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>

Atau opsi lain dengan rowwisedenganc_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))

-keluaran

# 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        

data

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

Berikut adalah pendekatan lain yang dapat Anda gunakan tanpa menggunakan paket apa pun.

Pertama, dapatkan data untuk kolom tanggal, dan dari situ Anda dapat menggunakan applyfungsi pada setiap baris untuk mendapatkan nilai maks dan min yang sesuai. Berikut contohnya:

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)

Data

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