【问题标题】:Finding column with closest date in R with dplyr使用 dplyr 在 R 中查找日期最近的列
【发布时间】:2019-02-08 20:47:22
【问题描述】:

我有一个包含主题列表和一组日期的数据框:

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

【问题讨论】:

    标签: r date dplyr lapply


    【解决方案1】:

    这是一种基本上使用整个 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")
    

    【讨论】:

      【解决方案2】:

      使用您的 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])
      })
      

      【讨论】:

        【解决方案3】:

        为了完整起见,这里还有一个解决方案,在将数据重新整形为长格式后使用滚动连接

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2020-05-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-06-30
          • 1970-01-01
          相关资源
          最近更新 更多