如何比较不同数据框中的日期并将值分配给一个数据框中的同一列,而另一数据框中的同一列?

时间:2019-04-10 15:42:23

标签: r

我有一个示例数据框,如下所示

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

所需的输出是:

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
               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

2 个答案:

答案 0 :(得分:0)

您要在此处执行的操作称为join,特别是您要使用df1 left_join df2,以便将所有行保留在df2中,然后从df1添加匹配的列。

要了解有关联接以及如何在R中使用联接的更多信息,请阅读以下相关问题:How to join (merge) data frames (inner, outer, left, right)

这里的复杂之处在于date列的偏移量为一秒钟。为此,我们只需要在加入之前使用date来修改lubridate::dseconds

首先,我们获取您的数据,并确保使用datePOSIXct格式化为lubridate::as_datetime,以便我们将其作为日期使用。

这将根据您的数据为我们提供以下数据框:

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了,但是请注意,我们使用df1$date在联接中修改了dplyr::mutate

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

如您所见,我们在general_id中添加了相应的df1列。然后,我们可以删除general_id.x并根据需要重命名general_id.y。请注意,第2行返回NA,因为它在df1中没有匹配项(时间匹配,但日期不同)

答案 1 :(得分:0)

以下代码检查date列中日期之间的时间差小于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)
}