【问题标题】:Mutate column based on another data frame with multiple matches根据具有多个匹配项的另一个数据框改变列
【发布时间】:2017-09-06 16:08:49
【问题描述】:

我有以下数据框

df1

ID    PMT_DATE
100   2015/01/01
100   2015/02/01
100   2015/04/01 
200   2016/01/01
200   2016/02/01

和 df2

ID    DATE         STATUS    
100   2014/12/31   A
100   2015/03/15   B
200   2015/12/31   A  
200   2016/06/01   C

我将创建一个数据框,它是 df1 和 df2 中的 STATUS 列。如果 df1 中的 PMT_DATE 列大于或等于 df2 中的 DATE 列,则 df2 中的关联状态应放置在新数据框中。生成的数据框应如下所示

ID    PMT_DATE     STATUS
100   2015/01/01   A
100   2015/02/01   A
100   2015/04/01   B 
200   2016/01/01   A
200   2016/02/01   A

通常我会加入这两个表,创建一个新列并使用 mutate 执行计算并删除我不再需要的列,但由于 df1 和 df2 中的 ID 列中有多个匹配项,我可以'没有完全实施该策略。

编辑:对于多场比赛,我想要最新的状态。例如,ID == 100 的最后一行将同时属于状态 == A 和状态 == B,但我只想要状态 B。此外,两个数据帧中的 ID 字段代表相同的东西(即通过 ID 连接是我想要的)。

我在想一些类似的东西

new_df <- df1 %>% rowwise() $>% do() ...

但我不确定如何填写其余部分以实现我所需要的。

【问题讨论】:

  • df1的第三行不应该是A和B的状态吗?

标签: r dplyr


【解决方案1】:

我不确定dplyr 是否可以使用滚动连接。这就是我要使用data.table 来获取最新 STATUS

library(data.table)
setDT(df2)[setDT(df1), on = .(ID, DATE = PMT_DATE), roll = Inf]
    ID       DATE STATUS
1: 100 2015-01-01      A
2: 100 2015-02-01      A
3: 100 2015-04-01      B
4: 200 2016-01-01      A
5: 200 2016-02-01      A

数据

df1 <- readr::read_table(
  "ID    PMT_DATE
100   2015/01/01
100   2015/02/01
100   2015/04/01 
200   2016/01/01
200   2016/02/01"
)
df2 <- readr::read_table(
  "ID    DATE         STATUS    
100   2014/12/31   A
100   2015/03/15   B
200   2015/12/31   A  
200   2016/06/01   C"
)

【讨论】:

  • 或者不做一个新表...setDT(df1); setDT(df2); df1[, v := df2[.SD, on=.(ID, DATE = PMT_DATE), roll=TRUE, x.STATUS]]
  • 或非等连接:df1[df2, on = .(ID, PMT_DATE &gt; DATE), STATUS := i.STATUS][]
【解决方案2】:

这是一种使用dplyr 的方法。这个想法是先加入表格并过滤掉带有PMT_DATE &gt;= DATE的行。我想你只想要最新的STATUSSTATUS 关联最新的DATE)。

library(dplyr)

df1 %>% 
  left_join(df2, by="ID") %>%
  filter(PMT_DATE >= DATE) %>% 
  group_by(ID, PMT_DATE) %>% 
  slice(n()) %>% # get the latest status
  select(-DATE) %>%
  ungroup()

# # A tibble: 5 x 3
#      ID   PMT_DATE STATUS
#   <int>      <chr>  <chr>
# 1   100 2015/01/01      A
# 2   100 2015/02/01      A
# 3   100 2015/04/01      B
# 4   200 2016/01/01      A
# 5   200 2016/02/01      A

【讨论】:

  • OP 是否指定需要通过 ID 执行连接? (注意我对你的方案没意见,觉得挺好的)
  • 嗯...实际上没有。我可能做了太多假设。我们可以要求 OP 澄清。
  • 对不起,我应该指定的,我想要的是通过 ID 加入。
  • @ArzaanK 你应该编辑你的问题,你还应该指定如何处理多个匹配项(ID == 100 和 PMT_DATE == 2015/04/01 的情况)
猜你喜欢
  • 2022-12-18
  • 2020-05-23
  • 2020-04-11
  • 1970-01-01
  • 2021-05-06
  • 2022-01-11
  • 1970-01-01
  • 1970-01-01
  • 2017-02-10
相关资源
最近更新 更多