Поиск столбца с ближайшей датой в R с помощью dplyr - PullRequest
0 голосов
/ 08 февраля 2019

У меня есть фрейм данных со списком субъектов и набором дат:

Subject    Date1       Date2       Date3      Date4      Date5     UniqueDate
001        12Mar02     03Apr02     08May02    09Jun02    22Jul02   02June02
002        15Feb05     03Mar05     18Apr05    01May05    16Jun05   22May05
...
100        22Jan09     01Feb09     28Mar09    10Apr09    21May09   29Jan09

Я хотел бы найти имя последнего столбца, которое больше чем UniqueDate.Так, например, результат для Subject 001 должен быть Date3.

У меня пока нет работающего решения, но сейчас я пытаюсь использовать это:

colnames(DF[, 2:5])[apply(DF,1,which.max(DF[i] - DF$UniqueDate)]

Ответы [ 3 ]

0 голосов
/ 09 февраля 2019

С вашим data.frame:

d <- data.frame("Subject" = c("001", "002", "003"),
                "Date1" = c("12Mar02", "15Feb05", "22Jan09"),
                "Date2" = c("03Apr02", "03Mar05", "01Feb09"),
                "Date3" = c("08May02", "18Apr05", "28Mar09"),
                "Date4" = c("09Jun02", "01May05", "10Apr09"),
                "Date5" = c("22Jul02", "16Jun05", "21May09"),
                "UniqueDate" = c("02June02", "22May05", "29Jan09"))

Сначала вы хотите превратить столбцы даты в форму, которую R распознает как даты:

d[, 2:7] <- lapply(d[, 2:7], as.Date, format = "%d%b%y")

Затем сохраните нужные результаты вновый столбец с именем result (примечание: это работает, только если даты в Date1-Date4 ранжируются от самых старых до самых последних:

d$result <- apply(d, 1, function(x){
  sum(x["UniqueDate"] > x[2:6])
})
0 голосов
/ 09 февраля 2019

Для полноты картины также существует решение, в котором используется скользящее соединение после преобразования данных в длинный формат:

library(data.table)
long <- melt(setDT(DT), "Subject")[
  , value := lubridate::dmy(value)][]
long[variable != "UniqueDate"][long[variable == "UniqueDate"], 
                               on = .(Subject, value), .(Subject, variable), roll = Inf]
   Subject variable
1:       1    Date3
2:       2    Date4
3:     100    Date1

Данные

library(data.table)
DT <- fread("
Subject    Date1       Date2       Date3      Date4      Date5     UniqueDate
001        12Mar02     03Apr02     08May02    09Jun02    22Jul02   02June02
002        15Feb05     03Mar05     18Apr05    01May05    16Jun05   22May05
100        22Jan09     01Feb09     28Mar09    10Apr09    21May09   29Jan09")
0 голосов
/ 09 февраля 2019

Вот одно решение, использующее в основном целое tidyverse:

library(dplyr)
library(tidyr)
library(purrr)
library(lubridate)

df %>% 
  nest(-Subject, -UniqueDate) %>% 
  mutate(latest_date = map2_chr(data, UniqueDate, ~ unlist(.x[max(which(dmy(.x) < dmy(.y)))])))

#> # A tibble: 3 x 4
#>   Subject UniqueDate data             latest_date
#>     <dbl> <chr>      <list>           <chr>      
#> 1       1 02June02   <tibble [1 x 5]> 08May02    
#> 2       2 22May05    <tibble [1 x 5]> 01May05    
#> 3     100 29Jan09    <tibble [1 x 5]> 22Jan09

Последняя строка немного беспорядочная - надеюсь, вы сможете увидеть, что здесь происходит.

Было бы интересно увидеть решение R для этого.

Данные

df <-
  tribble(~Subject,    ~Date1,       ~Date2,       ~Date3,      ~Date4,      ~Date5,     ~UniqueDate,
          001,        "12Mar02",     "03Apr02",     "08May02",    "09Jun02",    "22Jul02",   "02June02",
          002,        "15Feb05",     "03Mar05",     "18Apr05",    "01May05",    "16Jun05",   "22May05",
          100,        "22Jan09",     "01Feb09",     "28Mar09",    "10Apr09",    "21May09",   "29Jan09")
...