如何比较不同数据框中的日期并将值分配给另一个数据框中同一列的一个数据框中的同一列?
Posted
技术标签:
【中文标题】如何比较不同数据框中的日期并将值分配给另一个数据框中同一列的一个数据框中的同一列?【英文标题】:how to compare dates in different data frames and assign values to a same column in one dataframe of a same column in another dataframe? 【发布时间】:2019-09-01 03:34:09 【问题描述】:我有一个示例数据框,如下所示
Dataframe1.
general_id date
6 2000-01-02 16:57:13
2 2000-01-02 19:26:13
3 2000-01-04 13:30:13
2 2000-01-04 19:03:13
7 2000-01-06 16:32:13
Dataframe2.
general_id date
1 2000-01-02 16:57:12
1 2000-01-06 16:57:12
1 2000-01-02 19:26:12
1 2000-01-02 19:26:12
1 2000-01-04 13:30:12
1 2000-01-04 13:30:12
1 2000-01-04 19:03:12
1 2000-01-04 19:03:12
1 2000-01-06 16:32:12
数据框的两个日期列仅存在第二个差异。
我想比较两个数据框的日期列,并将 Dataframe1 中 general_id
列的值分配给 Dataframe2 中的 general_id
列
date1 <- Dataframe1$date-dsecond(1)
date2 <- Dataframe1$date
if(date1==date2)
dataframe2$general_id=dataframe1$general_id
但是我收到了这个错误,
In if (date1 == date2) the condition has length > 1 and only the first element will be used
期望的输出是:
数据框1
general_id date
6 2000-01-02 16:57:13
2 2000-01-02 19:26:13
3 2000-01-04 13:30:13
2 2000-01-04 19:03:13
7 2000-01-06 16:32:13
数据框2
general_id date
6 2000-01-02 16:57:12
6 2000-01-06 16:57:12
2 2000-01-02 19:26:12
2 2000-01-02 19:26:12
3 2000-01-04 13:30:12
3 2000-01-04 13:30:12
2 2000-01-04 19:03:12
2 2000-01-04 19:03:12
7 2000-01-06 16:32:12
7 2000-01-06 16:32:12
【问题讨论】:
请显示您正在使用的代码。此外,在这两种情况下,您想要的输出都只是 Dataframe1 。你能修改你的例子来说明为什么我们不能只使用Dataframe2 <- Dataframe1
吗?
How to join (merge) data frames (inner, outer, left, right)的可能重复
您似乎想对您的数据执行join_*
:dplyr::left_join(Dataframe2, Dataframe1, by = 'date')
,然后选择右侧的general_id
列。
但是dataframe2只有1秒的差异,我需要如何比较。
【参考方案1】:
以下代码检查日期列中日期之间的时间差是否小于 2 秒。要使其仅在一个方向上精确匹配 1 秒的时间差,请更改 which
语句。
for (i in 1:nrow(Dataframe2))
corresponding_row <- which(abs(as.POSIXct(Dataframe1$date)-as.POSIXct(Dataframe2$date[i]))<2)
message('row ', i, ' of Dataframe2 corresponds to row ', corresponding_row, ' of Dataframe1')
Dataframe2$id[i] <- ifelse(length(corresponnding_row), Dataframe1$id[corresponding_row], NA)
【讨论】:
【参考方案2】:您要在此处执行的操作称为join
,具体而言,您希望将left_join
df2 与df1 结合起来,以便将所有行保留在df2 中,然后从df1 添加匹配的列。
要了解有关联接的更多信息以及如何在 R 中使用它们,请阅读此相关问题:How to join (merge) data frames (inner, outer, left, right)
这里的复杂之处在于date
列关闭了一秒钟。为此,我们只需要在加入之前使用lubridate::dseconds
修改date
。
首先,我们获取您的数据并确保使用lubridate::as_datetime
将date
格式化为POSIXct
,以便我们可以将其用作日期。
这将根据您的数据为我们提供以下数据框:
df1 <- structure(list(general_id = c(6L, 2L, 3L, 2L, 7L), date = structure(c(946832233,
946841173, 946992613, 947012593, 947176333), class = c("POSIXct",
"POSIXt"), tzone = "UTC")), row.names = c(NA, -5L), class = "data.frame")
df2 <- structure(list(general_id = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L), date = structure(c(946832232, 947177832, 946841172, 946841172,
946992612, 946992612, 947012592, 947012592, 947176332), class = c("POSIXct",
"POSIXt"), tzone = "UTC")), row.names = c(NA, -9L), class = "data.frame")
现在我们可以使用join
,但请注意,我们在连接中使用dplyr::mutate
修改df1$date
:
library(dplyr)
left_join(df2, mutate(df1, date = date - lubridate::dseconds(1)), by = 'date')
general_id.x date general_id.y
1 1 2000-01-02 16:57:12 6
2 1 2000-01-06 16:57:12 NA
3 1 2000-01-02 19:26:12 2
4 1 2000-01-02 19:26:12 2
5 1 2000-01-04 13:30:12 3
6 1 2000-01-04 13:30:12 3
7 1 2000-01-04 19:03:12 2
8 1 2000-01-04 19:03:12 2
9 1 2000-01-06 16:32:12 7
如您所见,我们从df1
添加了适当的general_id
列。如果需要,我们可以删除general_id.x
并重命名general_id.y
。请注意,第 2 行返回 NA
,因为它在 df1
中没有匹配项(时间匹配,但日期不同)
【讨论】:
以上是关于如何比较不同数据框中的日期并将值分配给另一个数据框中同一列的一个数据框中的同一列?的主要内容,如果未能解决你的问题,请参考以下文章
如何按 > 日期对一系列日期求和并将它们附加到熊猫新数据框中的新列?