【问题标题】:Find the minimum date between two maximum dates based off unique values in a column根据列中的唯一值查找两个最大日期之间的最小日期
【发布时间】:2021-09-23 20:14:00
【问题描述】:

数据示例。

date1 = seq(as.Date("2019/01/01"), by = "month", length.out = 29)
date2= seq(as.Date("2019/05/01"), by = "month", length.out = 29)

subproducts1=rep("1",29)
subproducts2=rep("2",29)

b1 <- c(rnorm(29,5))
b2 <- c(rnorm(29,5))

dfone <- data.frame("date"= c(date1,date2),
                "subproduct"= 
                  c(subproducts1,subproducts2),
                "actuals"= c(b1,b2))

子产品 1 的最大日期为 2021 年 5 月,子产品 2 的最大日期为 2021 年 9 月。

问题:有没有办法:

  1. 找出唯一子产品的最大日期和
  2. 一步完成从两个最大日期中找出最小日期?

在这种情况下,最终结果应该是 2021 年 5 月,并且能够处理多个子产品。

【问题讨论】:

    标签: r dataframe dplyr data-manipulation


    【解决方案1】:

    我们可以在按“子产品”、pulldate 分组后使用slice_max,并得到min,将其分配给一个新对象

    library(dplyr)
    dfone %>%
        group_by(subproduct) %>%
        slice_max(n = 1, order_by = date) %>%
        ungroup %>%
        pull(date) %>%
        min -> Min_date
    

    -输出

     Min_date
    [1] "2021-05-01"
    

    另一种选择是arrange 行和filter 使用duplicated

    dfone %>%
        arrange(subproduct, desc(date)) %>% 
        filter(!duplicated(subproduct)) %>% 
        pull(date) %>%
        min
    

    【讨论】:

    • 有没有办法将最小日期作为变量或其他东西取出,因为我不需要它作为新列。我只需要它作为变量/对象。
    • @chriswang123456 你能检查更新吗
    • 将尝试实际代码,看看会发生什么。一瞬间
    【解决方案2】:

    对于您的第一个目标,您可以尝试subset + ave,如下所示

    out1 <- subset(
        dfone,
        ave(date, subproduct, FUN = max) == date
    )
    

    给了

             date subproduct  actuals
    29 2021-05-01          1 5.728420
    58 2021-09-01          2 3.455491
    

    对于你的第二个目标,基于out1,你可以试试

    out2 <- subset(
        out1,
        date == min(date)
    )
    

    给了

             date subproduct  actuals
    29 2021-05-01          1 5.083229
    

    【讨论】:

      【解决方案3】:

      这也可以在基础 R 中完成。最后我使用了Reduce,以便解决方案可以推广到任意数量的subproducts 和dates,而不仅仅是这里的 2 个值.

      Reduce(function(x, y) min(x, y),
             lapply(unique(dfone$subproduct), \(x){
               max(dfone$date[dfone$subproduct == x])
             }))
      
      [1] "2021-05-01"
      

      【讨论】:

      • 哦,哇,太棒了。如果我能给出两个最好的答案,我会的。谢谢你。
      • 我很高兴。谢谢您的好意。其他 Arun 和 Thomas 是真正的 R 大师。
      • 谢谢你,你真是太好了。是的,Norman Matloff 教授的 R 编程艺术很棒,Hadly Wickham 教授的 Advanced R 也应该至少阅读 5 次,您可以在下面的链接中在线阅读,最后在这里尽可能多地尝试尝试和练习无论何时出现问题:adv-r.hadley.nz
      • Hadley 的R for Data Science 也是一个好的开始。
      • 还有这个很棒的加上马丁提到的那个:rstudio-education.github.io/hopr
      【解决方案4】:

      为了完整起见,这里还有的解决方案:

      1.数据表

      library(data.table)
      setDT(dfone)[, max(date), by = subproduct][, min(V1)]
      

      [1]“2021-05-01”

      2. sqldf

      sqldf::sqldf("
      select min(date) from (
        select max(date) as date from dfone group by subproduct
      )", method = "Date")
      
         min(date)
      1 2021-05-01
      

      【讨论】:

        【解决方案5】:

        另一种尝试——将dfone数据按date降序排序,找到每个subproduct的第一个实例,取最小值:

        with(dfone[order(dfone$date, decreasing=TRUE),], 
             min(date[match(unique(subproduct), subproduct)]))
        #[1] "2021-05-01"
        

        【讨论】:

          【解决方案6】:

          虽然问题已被标记为已解决,但还有一个技巧可以使用 {} 匿名呼叫

          library(dplyr)
          
          dfone %>% group_by(subproduct) %>%
            summarise(d = max(date), .groups = 'drop') %>%
            {min(.$d)}
          
          #> [1] "2021-05-01"
          

          reprex package 创建于 2021-07-16 (v2.0.0)

          【讨论】:

          • 绝对的光彩。
          猜你喜欢
          • 1970-01-01
          • 2017-06-13
          • 2020-09-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多