根据列中的唯一值查找两个最大日期之间的最小日期

Find the minimum date between two maximum dates based off unique values in a column

数据示例。

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. 的最大日期
  3. 一步从两个最大日期中找出最小日期?

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

我们可以在'subproduct'分组后使用slice_maxpull date得到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

对于你的第一个目标,你可以像下面那样尝试 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

这也可以在基础 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"

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

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

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

1。 data.table

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

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

library(dplyr)

dfone %>% group_by(subproduct) %>%
  summarise(d = max(date), .groups = 'drop') %>%
  {min(.$d)}

#> [1] "2021-05-01"

reprex package (v2.0.0)

于 2021-07-16 创建