【发布时间】:2020-06-06 13:10:41
【问题描述】:
我有两个独立的数据集:df1 和 df2。我想创建一个新的数据集 df3,如果日期时间在 20 秒内,它将匹配 df1 的 endtime 列与 df2 的发送列。最后,我想创建一个最终数据集,为我提供 df2 数据集(已发送/ID 数据集)中与 df1 不匹配的所有值。
df1
endtime ID
1/7/2020 1:35:08 AM A
1/7/2020 1:39:00 AM B
1/20/2020 1:45:00 AM C
df2
sent ID
1/7/2020 1:35:20 AM E
1/7/2020 1:42:00 AM F
1/20/2020 1:55:00 AM G
1/20/2020 2:00:00 AM E
这是我想要的 df3 输出。只有一行,因为只有两个值符合 endtime 和 sent 列的 20 秒内的条件。
endtime sent
1/7/2020 1:35:08 AM 1/7/2020 1:35:20 AM
不匹配值的期望输出
sent
1/7/2020 1:42:00 AM
1/20/2020 1:55:00 AM
1/20/2020 2:00:00 AM
这是输出:
df1
structure(list(endtime = structure(c(2L, 3L, 1L), .Label = c("1/10/2020 1:45:00 AM",
"1/7/2020 1:35:08 AM", "1/7/2020 1:39:00 AM"), class = "factor"),
ID = structure(1:3, .Label = c("A", "B", "C"), class = "factor")), class = "data.frame", row.names = c(NA,
-3L))
df2
structure(list(sent = structure(c(3L, 4L, 1L, 2L), .Label = c("1/20/2020 1:55:00 AM",
"1/20/2020 2:00:00 AM", "1/7/2020 1:35:20 AM", "1/7/2020 1:42:00 AM"
), class = "factor"), ID = structure(c(1L, 2L, 3L, 1L), .Label = c("E",
"F", "G"), class = "factor")), class = "data.frame", row.names = c(NA,
-4L))
这是我尝试过的:
我正在考虑执行左连接并匹配值,或者我可以使用 merge(),但棘手的部分是将值与条件语句匹配。任何建议表示赞赏。
df3<-crossing(endtime = as.POSIXct(df1$endtime,format ="%m/%d/%Y %I:%M:%S %p" ),
sent = as.POSIXct(df2$sent, format = "%m/%d/%Y %I:%M:%S %p")) %>%
filter((endtime - seconds(20)) <= sent,
(endtime + seconds(20)) >= (sent)) %>%
mutate_all(format, format = "%m/%d/%Y %I:%M:%S %p") %>%
distinct(sent, .keep_all = TRUE)
这很好用,但我不知道如何在 df2 数据集中找到基本上“剩余”且没有匹配项的所有值。任何建议表示赞赏。
【问题讨论】:
-
您可以将
ID列添加到每个原始data.frame 并检查IDs 不在df3中,即df1$ID[!df1$ID %in% df3$ID, ]... -
好主意! @dario
-
但这只是显示的日期。在显示数据时更改它,但出于内部目的,将其保留为日期...但是您可以随意做,这是您的数据;)
-
嗨,Tanisha。请再次阅读下面关于答案的 cmets(我在那里解释了原始代码的问题并提出了两种解决方案)。如果您仍有问题,请随时提出。
-
对不起,我可能有点不清楚。不,更改不是为了保持一致性,实际上它有点不一致,因为 df1 和 df2 仍然 使用 AM/PM。我们不得不做出改变,因为出现了问题。您在问题中显示的代码存在未显示 AM/PM 的错误。只看df3的输出。没有 AM 或 PM ..(我在答案中编辑开始时显示的 tibble 表明)。这是一个问题,因为这样我们无法区分 11h 和 23h!?这就是为什么我在我的编辑中建议 df3 的改编代码。修复错误。
标签: r dplyr data.table lubridate stringr