【问题标题】:Mutate min date per group using filter conditions in dplyr使用 dplyr 中的过滤条件更改每组的最小日期
【发布时间】:2020-05-20 21:52:17
【问题描述】:

我希望创建一个新列,其中包含满足某些条件的每个组的最短日期。

我的数据如下:

mbr <- c('A','A','A','A','B','B','B')
drg_typ <- c('TGT','TGT','TGT','Other','Other','TGT','TGT')
dt <- as.Date(c('2018-01-01','2019-06-30','2019-03-18','2017-01-01','2018-01-01','2016-01-01','2019-05-01'))

df <- data.frame(mbr,drg_typ,dt)

mbr drg_typ dt
A   TGT     2018-01-01
A   TGT     2019-06-30
A   TGT     2019-03-18
A   Other   2017-01-01
B   Other   2018-01-01
B   TGT     2016-01-01
B   TGT     2019-05-01

我希望改变一个名为 min_dt 的新列,该列在mbr 的组级别使用以下逻辑执行:

对于 drg_typ = 'TGT' 且 dt 介于 2019-01-01 和 2019-12-31 之间的每个 mbr,请填写一个名为 min_dt 的新列,其中 dt 的最小值介于上述日期值之间。

我试过了:

df <- df %>% 
  group_by(mbr) %>%
  mutate(min_dt = if_else(drg_typ == 'TGT' & dt >= '2019-01-01' & dt <= '2019-12-31', min(dt),0))

但我收到以下错误:

Error in as.Date.numeric(value) : 'origin' must be supplied

我检查了我的数据框的结构,dt 是一个日期

> str(df)
'data.frame':   7 obs. of  3 variables:
 $ mbr    : Factor w/ 2 levels "A","B": 1 1 1 1 2 2 2
 $ drg_typ: Factor w/ 2 levels "Other","TGT": 2 2 2 1 1 2 2
 $ dt     : Date, format: "2018-01-01" "2019-06-30" "2019-03-18" "2017-01-01" ...

我的最终输出应该如下所示:

 mbr drg_typ    dt         min_dt
    A   TGT     2018-01-01 2019-03-18
    A   TGT     2019-06-30 2019-03-18
    A   TGT     2019-03-18 2019-03-18
    A   Other   2017-01-01 2019-03-18
    B   Other   2018-01-01 2019-05-01
    B   TGT     2016-01-01 2019-05-01
    B   TGT     2019-05-01 2019-05-01

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    0 是一个问题,if_else 检查类型。这里trueDate 类,而false 是数字。相反,它可以是 NA 并将其转换为 Dateas.Date

    library(dplyr)
    df %>% 
       group_by(mbr) %>%
       mutate(min_dt = if_else(drg_typ == 'TGT' & 
           dt >= '2019-01-01' & dt <= '2019-12-31', min(dt), as.Date(NA)))
    

    根据预期的输出,我们这里不需要if_else。 'dt' 的min 可以基于逻辑表达式

    df %>%
         group_by(mbr) %>%
          mutate(min_dt = min(dt[drg_typ == 'TGT' & 
             between(dt, as.Date('2019-01-01'), as.Date('2019-12-31'))]))
    # A tibble: 7 x 4
    # Groups:   mbr [2]
    #  mbr   drg_typ dt         min_dt    
    #  <fct> <fct>   <date>     <date>    
    #1 A     TGT     2018-01-01 2019-03-18
    #2 A     TGT     2019-06-30 2019-03-18
    #3 A     TGT     2019-03-18 2019-03-18
    #4 A     Other   2017-01-01 2019-03-18
    #5 B     Other   2018-01-01 2019-05-01
    #6 B     TGT     2016-01-01 2019-05-01
    #7 B     TGT     2019-05-01 2019-05-01
    

    或使用data.table

    library(data.table)
    setDT(df)[, min_dt := min(dt[drg_typ == 'TGT' & 
             between(dt, as.Date('2019-01-01'), as.Date('2019-12-31'))]), mbr]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-07-23
      • 2021-01-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多