【问题标题】:Update dataframe column by group according to match with another dataframe in R根据与 R 中另一个数据框的匹配,按组更新数据框列
【发布时间】:2017-08-02 20:19:43
【问题描述】:

我有两个数据框:

df1
ID    Date           Value
A     2017-01-01     3
B     2017-01-01     3
C     2017-01-01     3
C     2017-01-02     3
C     2017-01-03     3
D     2017-01-01     3

df2
ID    Date           Ratio
C     2017-01-01     3    

如果满足以下两个条件,我想从 df2 中的相应条目更新 df1 中的值,使得 Value = Value * Ratio:

  1. df1 中的 ID 与 df2 中的 ID 匹配
  2. df1 中的日期在 df2 中的日期之后

这是我想要的输出:

df1
ID    Date           Value
A     2017-01-01     3
B     2017-01-01     3
C     2017-01-01     3
C     2017-01-02     9
C     2017-01-03     9
D     2017-01-01     3

有什么帮助吗?我正在考虑使用聚合和匹配,但不知道如何将它们拼凑在一起。

【问题讨论】:

  • 嗨@Anna,您收到了几个很好的答案。请考虑接受对您有用的解决方案。这让社区知道答案有效并且问题已关闭。

标签: r


【解决方案1】:

使用data.table非等连接;使用 := 更新匹配行的 Value 列:

library(data.table)
setDT(df1); setDT(df2);

df1[df2, on = .(ID = ID, Date > Date), Value := Value * Ratio]

df1
#   ID       Date Value
#1:  A 2017-01-01     3
#2:  B 2017-01-01     3
#3:  C 2017-01-01     3
#4:  C 2017-01-02     9
#5:  C 2017-01-03     9
#6:  D 2017-01-01     3

感谢@Frank,这是ID = ID 的语法糖:

df1[df2, on = .(ID, Date > Date), Value := Value * Ratio]

【讨论】:

  • @Frank Exactly.
  • 感谢@Psidom 和@Frank!我实际上收到错误“未使用的参数(on = .(ID = ID, Date > Date))” - 任何线索这意味着什么?
  • 您使用的是什么 data.table 版本?您可能需要升级您的 data.table 包。如果我没记错的话,在 1.10.0+ 版本中引入了非 equi 连接。
  • 或者,您可能错过了 setDT 步骤,@Anna,因为自 2015 年 9 月 CRAN 版本的软件包以来,on= 一直是一个有效参数。
【解决方案2】:

通过ID合并df1和df2,仅在满足条件时更改Value,取消选择副作用列,将列重命名为原始名称

library(dplyr)
desired <- left_join(df1, df2, by="ID") %>%
             mutate(Value=ifelse(is.na(Date.x > Date.y), Value, Value*Ratio)) %>%
             select( -Date.y, Ratio ) %>%
             setNames( c("ID","Date","Value") )

【讨论】:

  • 感谢@Chi Pak!这很好,除了一个细节——我注意到参数是 Date.x > Date.y(又名严格大于);但是,我的输出显示了与 ID C 对应的所有条目的变异值。你知道如何解决这个问题吗?
  • 只是一个猜测...你是Dates as.Dates 还是characters
  • 我使用df2&lt;-data.frame(c("C"), c(as.Date("2017-01-01")), c(3)) 将它们转换为日期,但是当我检查typeof(df2$Date) 时,我得到了两倍...我猜这可能是为什么?
  • 是的,从日期到数字的转换很可能是不切实际的
猜你喜欢
  • 2020-05-23
  • 1970-01-01
  • 2017-02-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多