R의 각 행에서 가장 이른 날짜와 가장 늦은 날짜 찾기 [중복]

Dec 02 2020

온라인 플랫폼의 특정 사용자 입력 요소와 각 입력이 발생한 시간을 나타내는 400 개 이상의 열이있는 대용량 데이터 세트가 있습니다. 각 행은 사용자 ID를 나타냅니다.

이러한 열 중 200 개는 "POSIXct" "POSIXt"클래스 (예 : 2019-11-04 15:33:50)이며 모든 요소가 모든 사용자에게 표시되거나 채워지지는 않기 때문에 누락 된 값이 발생할 수 있습니다.

내 목표는 200 개의 "POSIXct" "POSIXt"열 각각의 행당 가장 이른 날짜와 가장 최근 날짜를 포함하는 두 개의 추가 열을 만드는 것입니다.

여기에 프레임의 간단한 예와 원하는 추가 열 중 하나가 있습니다. (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를 무시하면서 값).

답변

2 akrun Dec 02 2020 at 01:11

pmaxpmin'날짜'열을 사용하여 각 행의 가장 이른 날짜와 가장 최근 날짜를 반환 할 수 있습니다.

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



  
Neeraj Dec 02 2020 at 02:58

다음은 패키지를 사용하지 않고 사용할 수있는 또 다른 방법입니다.

먼저 날짜 열에 대한 데이터를 가져오고 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))