Взять минимальную дату / значение каждой строки после первого NA и до последнего NA? - PullRequest
2 голосов
/ 19 июня 2019

Я пытаюсь взять минимальную дату в последовательности дат, которая идет после всех NA перед этой последовательностью, и единственное, что после этой последовательности - это либо NA, либо эта последовательность дат - это последние столбцы.

Это лучше объяснить на примере:

sample <- data.frame(subject = c("A","B","C"),Date1 = c("1-2-19","1-2-19",NA),Date2 = c("1-3-19",NA,"1-3-19"),Date3 = c("1-4-19","1-4-19",NA)
           ,Date4 = c(NA,"1-5-19",NA),Date5 = c("1-6-19",NA,NA),Date6 = c("1-7-19",NA,"1-7-19"))

Ouput:

subject  Date1  Date2  Date3  Date4  Date5  Date6
1       A 1-2-19 1-3-19 1-4-19   <NA> 1-6-19 1-7-19
2       B 1-2-19   <NA> 1-4-19 1-5-19   <NA>   <NA>
3       C   <NA> 1-3-19   <NA>   <NA>   <NA> 1-7-19

Ожидаемый результат должен иметь дополнительный столбец с именем Minimum_Date, в который вводится ожидаемый результат для каждой строки.

Таким образом, субъект А вернул бы '1-6-19'

Субъект B вернул бы '1-4-19'

Субъект C вернул бы '1-7-19'

Ответы [ 2 ]

3 голосов
/ 19 июня 2019

Вот опция в base R

sample$minDate <- apply(sample[-1], 1, function(x) {
       i1 <- which(!is.na(x))
       mx <- cumsum(c(TRUE, diff(i1) != 1))
       x1 <- x[i1[mx == max(mx)]]
       x1[which.min(as.Date(x1, "%m-%d-%y"))]})
sample$minDate
#[1] "1-6-19" "1-4-19" "1-7-19"
2 голосов
/ 19 июня 2019

Вот подход tidyverse, который преобразуется в длинный формат для достижения желаемого результата.

library(tidyverse)
sample <- data.frame(subject = c("A","B","C"),Date1 = c("1-2-19","1-2-19",NA),Date2 = c("1-3-19",NA,"1-3-19"),Date3 = c("1-4-19","1-4-19",NA)
                     ,Date4 = c(NA,"1-5-19",NA),Date5 = c("1-6-19",NA,NA),Date6 = c("1-7-19",NA,"1-7-19"))

sample %>%
  gather(date_num, date, -subject) %>% #reshape longer
  mutate(date = lubridate::mdy(date)) %>% # convert to date so min works
  arrange(subject, desc(date_num)) %>% # sort in reverse order
  group_by(subject) %>%
  mutate(after_na = cumsum(is.na(date))) %>% # create indicator for how many NAs have appeared
  filter(!is.na(date)) %>% # deal with rows that end in NA
  filter(after_na == min(after_na)) %>% # restrict to the last sequence
  summarise(Minimum_Date = min(date)) %>% # get min of those dates in last sequence
  inner_join(sample) # join onto original table
#> # A tibble: 3 x 8
#>   subject Minimum_Date Date1  Date2  Date3  Date4  Date5  Date6 
#>   <fct>   <date>       <fct>  <fct>  <fct>  <fct>  <fct>  <fct> 
#> 1 A       2019-01-06   1-2-19 1-3-19 1-4-19 <NA>   1-6-19 1-7-19
#> 2 B       2019-01-04   1-2-19 <NA>   1-4-19 1-5-19 <NA>   <NA>  
#> 3 C       2019-01-07   <NA>   1-3-19 <NA>   <NA>   <NA>   1-7-19

Создан в 2019-06-18 пакетом Представить (v0.3.0)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...