【问题标题】:R - 2 dataframes, sum values on dataframe 2 between dates on dataframe 1 matching ID#R - 2 个数据帧,在数据帧 1 匹配 ID 的日期之间对数据帧 2 的值求和#
【发布时间】:2018-04-17 18:47:43
【问题描述】:

我有 2 个数据框。

data frame 1 includes : ID, date1, date2
data frame 2 includes : ID, date , amount

我想在数据框 1 中创建另一列,汇总数据框 2 中位于数据框 1 中 date1date2match ID 之间的金额。

我已经尝试了一些使用 dplyr 的方法,包括使用 lubridate 在数据框一中创建一个间隔列,但仍然无法解决这个问题。

另外,我应该提到,数据框 2 对每个 ID 都有多个列表。它具有该月每个 ID 的每一天的金额。因此,它就像 excel 中的 sumifs 函数,但对于 R。如果 id 匹配并且日期是 btw date1 和 date2,则对 df2 中的所有金额求和。

【问题讨论】:

  • 请提供可重复的数据和问题,以便其他人更容易回答。

标签: r lubridate sumifs dplyr


【解决方案1】:

基于dplyr 的解决方案可以是:

library(dplyr)

df2 %>% left_join(df1, by="ID") %>%
  filter(between(date, date1, date2) %>%
  group_by(date) %>%
  mutate(sum_amount = sum(amount))

注意:以上解决方案假定datedate1date2 的类型为DatePOSIXct 类型。

【讨论】:

  • 这太棒了!但我不能加入,因为 df2 中的列数比 df1 多。 df2 是一个月内每个 id 每天的分配。所以我们会看到一个 ID 被列出了 30 次
  • @ANN df2 中的更多列不是问题。如果我对您的理解正确,您会收到很多 df2(每天 1 个)。这也不是问题。您可以使用bind_rows 将所有df2s 合并到一个data.frame 中。然后你可以加入df1。如果您可以分享可重现的示例和预期结果会更好。
  • 非常感谢您的帮助。这是我收到的错误 filter_impl(.data, quo) 中的错误:评估错误:期望单个值:[extent=3054256].. 另外:警告消息:列NAME 加入不同级别的因素,强制转换为字符向量
  • 我无法共享数据,但我正在尝试查看如何共享数据样本。
  • 好的修复了在另一部分工作的部分错误 filter_impl(.data, quo) 中的错误:评估错误:期望单个值:[extent=352]
【解决方案2】:

这里是一个使用fuzzyjoin包的例子。

library(tibble)
library(lubridate)
library(fuzzyjoin)

df1 <- tibble(
  id = c("I1", "I2", "I3"),
  date1 = ymd(c("2006-01-01", "2007-01-01", "2008-01-01")),
  date2 = ymd(c("2006-12-31", "2007-12-31", "2008-12-31"))
)

df2 <- tibble(
  id = c("I1", "I1", "I2", "I2", "I3", "I3"),
  datetrans = ymd(c("2006-06-06", "2008-03-31", "2007-05-04",
                    "2007-08-09", "2009-01-01", "2009-10-12")),
  amount = c(100, 150, 75, 100, 200, 200)
)

df3 <- fuzzy_inner_join(df2, df1,
                        by = c("id" = "id",
                               "datetrans" = "date1", "datetrans" = "date2"),
                        match_fun = list(`==`, `>=`, `<=`))
df3 <- df3 %>%
  group_by(id.x) %>%
  summarise(amount = sum(amount))
colnames(df3) <- c("id", "amount")

result <- left_join(df1, df3)

创建数据集 df1 和 df2。请注意,对于 id I3,在 date1 和 date2 之间没有出现“日期”。

我们首先找到 df2 和 df1 之间的所有记录,其中 id 匹配并且 datetrans 变量在 date1 和 date2 之间。我们通过 id 汇总金额对结果进行分组。最后,将此数据集合并回 df1 以获得所需的输出。

【讨论】:

  • 非常感谢!但我收到一个错误,可能是由于 df2.xml 中有多个包含相同 ID 号的行。我本来应该指定的,对不起! Ops.factor(rep(u_x, n_y), rep(u_y, each = n_x), ...) 中的错误:因子的水平集不同
  • @ANN 如果你看到我的示例表,每个 id 都在 df2 中出现多次,所以上面的代码没有问题。我猜这个错误是因为 id 也是你的数据集中的一个因素,这就是你得到这个错误的原因。
  • 你是对的!对困惑感到抱歉。我想通了:)非常感谢你
猜你喜欢
  • 2020-05-24
  • 1970-01-01
  • 2021-03-17
  • 2018-09-27
  • 1970-01-01
  • 2019-11-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多