簡體   English   中英

如何使用 R/dplyr 根據條件加入?

[英]How to join based on a criteria using R/dplyr?

這里有一項艱巨的任務和一項更艱巨的任務……

假設有一個數據集如下:

DF1

ID     source                    timestamp
001         D       3/17/2021   1:22:10 AM
002         A       1/02/2021   8:25:20 AM         
002         A       5/17/2021  10:25:20 PM
003         B       5/11/2021   8:25:20 AM
003         D       5/17/2021   3:12:30 PM
004         A       5/17/2021   8:25:20 AM
004         B       5/17/2021   8:26:20 PM
004         C       5/17/2021   8:27:20 PM

注意:時間戳是一個變量中的日期和時間)

我需要做的就是擁有一個新的 dataframe,它只是最新條目的ID, SOURCE, AND TIMESTAMP

最終結果應該是這樣的:

ID     source                    timestamp
001         D       3/17/2021   1:22:10 AM
002         A       5/17/2021  10:25:20 PM
003         D       5/17/2021   3:12:30 PM
004         C       5/17/2021   8:27:20 PM

完全分開,我有這個數據集:

DF2

ID      event                    timestamp
001         y       3/17/2021   1:23:10 AM
002         y       3/12/2021  12:25:20 PM
003         y       5/12/2021   1:12:30 PM
004         y       5/17/2021   8:26:30 AM

我想根據最近的 ID將 DF2 加入 DF1。 我的意思是,DF1 有 2 個ID = 002條目。 我希望 DF2 在 ID 上加入,但僅限於最接近的時間戳而不過去。

最后結果:

ID     source               df1.1timestamp   event
001         D       3/17/2021   1:22:10 AM       y
002         A       1/02/2021   8:25:20 AM       y  
002         A       5/17/2021  10:25:20 PM
003         B       5/11/2021   8:25:20 AM       y
003         D       5/17/2021   3:12:30 PM
004         A       5/17/2021   8:25:20 AM
004         B       5/17/2021   8:26:20 PM       y
004         C       5/17/2021   8:27:20 PM

正如您在此處看到的, DF2中的事件已連接到DF1中的最新時間戳。 ID = 004的情況下,連接發生在5/17/2021 8:26:20 PM ,因為在DF2中,事件發生在5/17/2021 8:26:30 AM 5/17/2021 8:26:20 PMDF1中的行,它是緊接在事件之前的事件。

這種類型的連接在 dplyr* 中不容易實現,所以這里有一個 data.table 解決方案。

讀入數據。 以后請使用dput以便用戶可以將示例數據直接輸入到他們的 session 中。

library(data.table)

df1 <- fread('
ID     , source    ,               timestamp
001    ,      D    ,   3/17/2021   1:22:10 AM
002    ,      A    ,   1/02/2021   8:25:20 AM         
002    ,      A    ,   5/17/2021  10:25:20 PM
003    ,      B    ,   5/11/2021   8:25:20 AM
003    ,      D    ,   5/17/2021   3:12:30 PM
004    ,      A    ,   5/17/2021   8:25:20 AM
004    ,      B    ,   5/17/2021   8:26:20 PM
004    ,      C    ,   5/17/2021   8:27:20 PM
')

df2 <- fread('
ID      , event ,                   timestamp
001     ,     y     ,  3/17/2021   1:23:10 AM
002     ,     y     ,  3/12/2021  12:25:20 PM
003     ,     y     ,  5/12/2021   1:12:30 PM
004     ,     y     ,  5/17/2021   8:26:30 AM
')

# not required here, but would be if not read in as data.table
setDT(df1)
setDT(df2)

格式化日期時間並為 data.tables 設置鍵

df1[, timestamp := as.POSIXct(timestamp, format = '%m/%d/%Y %r')]
df2[, timestamp := as.POSIXct(timestamp, format = '%m/%d/%Y %r')]

setkey(df1, ID, timestamp)
setkey(df2, ID, timestamp)

第1部分


df1[, tail(.SD, 1), ID]
#>    ID source           timestamp
#> 1:  1      D 2021-03-17 01:22:10
#> 2:  2      A 2021-05-17 22:25:20
#> 3:  3      D 2021-05-17 15:12:30
#> 4:  4      C 2021-05-17 20:27:20

第2部分:

df1[df2, event := i.event, on = .(ID), mult = 'first']

df1
#>    ID source           timestamp event
#> 1:  1      D 2021-03-17 01:22:10     y
#> 2:  2      A 2021-01-02 08:25:20     y
#> 3:  2      A 2021-05-17 22:25:20  <NA>
#> 4:  3      B 2021-05-11 08:25:20     y
#> 5:  3      D 2021-05-17 15:12:30  <NA>
#> 6:  4      A 2021-05-17 08:25:20     y
#> 7:  4      B 2021-05-17 20:26:20  <NA>
#> 8:  4      C 2021-05-17 20:27:20  <NA>

reprex package (v2.0.1) 創建於 2021-09-30

* 雖然看起來很快: https://github.com/tidyverse/dplyr/pull/5910

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM