【问题标题】:Group two dfs based on dates that closely match根据紧密匹配的日期对两个 dfs 进行分组
【发布时间】:2021-02-24 00:54:33
【问题描述】:

这些是两个数据帧的子集。

df1:

plot mean_first_flower_date gdd
1 2019-07-15 60
1 2019-07-21 50
1 2019-07-23 78
2 2019-05-13 100
2 2019-05-22 173
2 2019-05-25 245

(续)

df2:

plot date flowers
1 2019-07-12 2
1 2019-07-13 9
1 2019-07-14 3
1 2019-07-15 3
2 2019-05-12 10
2 2019-05-13 10
2 2019-05-14 14
2 2019-05-15 17

(续)

df2 有一些与 df1 匹配的日期,但有时日期会关闭一天或几天(以粗体突出显示)。

我想根据“日期”和“绘图”对两个 df 进行分组,保留 df2,而不会丢失 df1 中的“gdd”数据。

例如,如果由于日期不匹配,我 inner_join 两个 dfs,就会发生这种情况。

因此,如果 df1 中的日期比 df2 中可能匹配的日期早或晚一到三天,那很好,因为日期相对接近。这很棘手,因为只有当 df1 中没有该数据范围的可用数据时,我才需要此数据替换。

我的目标是拥有这样的东西:

plot date flowers gdd
1 2019-07-12 2 60
1 2019-07-13 9 60
1 2019-07-14 3 60
1 2019-07-15 3 60
2 2019-05-12 10 100
2 2019-05-13 10 100
2 2019-05-14 14 100
2 2019-05-15 17 100

可以吗?

非常感谢任何帮助! 谢谢!

【问题讨论】:

  • df1 中 plot==2 的日期应该在 5 月而不是 7 月?
  • 是的,你是对的。
  • 您想在结果连接中填写NAs,但是如果一个图中有两个或多个值,填写/采用的标准是什么?

标签: r dataframe merging-data


【解决方案1】:

我认为 data.table 包中的“滚动连接”可以处理这个问题:

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

df1[, mean_first_flower_date := as.Date(mean_first_flower_date)]
df2[, date := as.Date(date)]

df1[df2, on=c("plot","mean_first_flower_date==date"), roll=3, rollends=TRUE]

#   plot mean_first_flower_date gdd flowers
#1:    1             2019-07-12  60       2
#2:    1             2019-07-13  60       9
#3:    1             2019-07-14  60       3
#4:    1             2019-07-15  60       3
#5:    2             2019-05-12 100      10
#6:    2             2019-05-13 100      10
#7:    2             2019-05-14 100      14
#8:    2             2019-05-15 100      17

使用这些数据:

df1 <- read.table(text="plot  mean_first_flower_date  gdd
1  2019-07-15  60
1  2019-07-21  50
1  2019-07-23  78
2  2019-05-13  100
2  2019-05-22  173
2  2019-05-25  245", header=TRUE)

df2 <- read.table(text="plot  date  flowers
1  2019-07-12  2
1  2019-07-13  9
1  2019-07-14  3
1  2019-07-15  3
2  2019-05-12  10
2  2019-05-13  10
2  2019-05-14  14
2  2019-05-15  17", header=TRUE)

【讨论】:

  • 我在运行代码的最后一行后收到此消息:错误 in vecseq(f__, len__, if (allow.cartesian || notjoin || !anyDuplicated(f__, : Join results in 33674 rows) ; 超过 31079 = nrow(x)+nrow(i)。检查 i 中的重复键值,每个键值都一遍又一遍地加入 x 中的同一组。如果没问题,请尝试 by=.EACHI 运行 j每个组以避免大分配。如果您确定要继续,请重新运行 allow.cartesian=TRUE。否则,请在 FAQ、Wiki、Stack Overflow 和 data.table 问题跟踪器中搜索此错误消息以获取建议。
  • 尝试将建议的参数添加到调用中 - 如消息所述,df1[df2, ..., allow.cartesian=TRUE]。或者在mean_first_flower_date检查重复的键值 - 如果您有许多日期与许多 +3/-3 日期范围匹配,您将得到重复。
  • @user3508884 请分享一些在一个绘图中匹配多行的行。在共享的样本数据中,每个地块只有一个匹配项。
【解决方案2】:

dplyr 尝试fill。使用这种语法

df2 %>% left_join(df1, by = c("plot" = "plot", "date" = "mean_first_flower_date")) %>%
  fill(gdd, .direction = "up")

  plot       date flowers gdd
1    1 2019-07-12       2  60
2    1 2019-07-13       9  60
3    1 2019-07-14       3  60
4    1 2019-07-15       3  60
5    2 2019-05-12      10 100
6    2 2019-05-13      10 100
7    2 2019-05-14      14  NA
8    2 2019-05-15      17  NA

您可以注意到最后两行中有两个NAs,如果您加入实际的df2,这些行将不应该存在173,因为会有一个匹配2019-05-22。如果你想填充最后的 NA 行,如果有的话,你可以再次使用 fill.direction = "down"

df2 %>% left_join(df1, by = c("plot" = "plot", "date" = "mean_first_flower_date")) %>%
  fill(gdd, .direction = "up") %>% fill(gdd, .direction = "down")

  plot       date flowers gdd
1    1 2019-07-12       2  60
2    1 2019-07-13       9  60
3    1 2019-07-14       3  60
4    1 2019-07-15       3  60
5    2 2019-05-12      10 100
6    2 2019-05-13      10 100
7    2 2019-05-14      14 100
8    2 2019-05-15      17 100

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-17
    • 2010-11-06
    • 1970-01-01
    • 2014-12-20
    相关资源
    最近更新 更多