Rの各行内で最も早い日付と最も遅い日付を検索します[重複]
オンラインプラットフォームからの特定のユーザー入力要素と各入力が発生した時刻を表す400を超える列を持つ大規模なデータセットがあります。各行はユーザーIDを表します。
これらの列のうち200個はクラス「POSIXct」「POSIXt」(例:2019-11-04 15:33:50)であり、すべての要素がすべてのユーザーに表示または入力されるわけではないため、値が欠落する可能性があります。
私の目標は、200個の「POSIXct」「POSIXt」列のそれぞれの行ごとに最も早い日付と最も遅い日付を含む2つの追加の列を作成することです。
ここでは、フレームと必要な追加の列の1つの簡略化された例を示します。(ID 4は、わざわざサイドを開くことはありませんが、他のデータソースからのデータを利用できるため、今のところデータセットに残しておく必要があります)
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
これまでのところ、他の日付以外の列を除外することについては、これ以上進んでいません。
is.POSIXt <- function(x) inherits(x, "POSIXt")
df%>%select(where(is.POSIXt))
選択の代わりに、おそらくmutate_atなどを条件として使用する必要がありますが、残りの200の日付/時刻列をすべてチェックしてから、新しく作成された列に最も早い/最も遅い日付を割り当てる(NAを無視する)ための最良の方法は何ですか?値)。
回答
'date'列でpmax
andpmin
を使用して、各行の最も早い日付と最も遅い日付を返すことができます
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>
または別のオプションrowwise
を持ちますc_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))
-出力
# 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
データ
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))
これは、パッケージを使用せずに使用できる別のアプローチです。
まず、日付列のデータを取得し、そこからapply
各行の関数を使用して、それに応じて最大値と最小値を取得できます。次に例を示します。
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)
データ
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))