Temukan tanggal paling awal dan terbaru dalam setiap baris di R [duplikat]
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
Kita dapat menggunakan pmax
dan pmin
pada 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 rowwise
denganc_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))
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 apply
fungsi 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))