簡體   English   中英

R:比較兩個data.frames並刪除不匹配的數據

[英]R: Compare two data.frames and delete data that not match

我有兩個data.frame時間序列。 第一個完成,第二個僅包含具有一個變量正確值的時間步長。 我需要保留所有其他變量,但要不顯示第二個df中出現的所有變量。 這里的例子:

library(dplyr)
library(tidyverse)
library(lubridate)

#test data:
TDF <- tibble(DATE = seq( make_datetime(2007,09,23,06,00), make_datetime(2008,07,05,23,00), by = 600),
          V1 = round(runif(length(DATE)),2),
          V2 = round(runif(length(DATE)),2),
          V3 = round(runif(length(DATE)),2))
TDF2 <- TDF
TDF2 <- TDF2[TDF2$V1>0.7,]

輸出:

> TDF
# A tibble: 41,287 × 4
                  DATE    V1    V2    V3
                <dttm> <dbl> <dbl> <dbl>
1  2007-09-23 06:00:00  0.89  0.21  0.03
2  2007-09-23 06:10:00  0.26  0.54  0.70
3  2007-09-23 06:20:00  0.74  0.22  0.80
4  2007-09-23 06:30:00  0.31  0.48  0.38
5  2007-09-23 06:40:00  0.93  0.26  0.21

> TDF2
# A tibble: 11,972 × 4
                  DATE    V1    V2    V3
                <dttm> <dbl> <dbl> <dbl>
1  2007-09-23 06:00:00  0.89  0.21  0.03
2  2007-09-23 06:20:00  0.74  0.22  0.80
3  2007-09-23 06:40:00  0.93  0.26  0.21
4  2007-09-23 07:20:00  0.91  0.36  0.83
5  2007-09-23 07:40:00  0.95  0.87  0.91

這就是我需要的:

> TDF_modified
# A tibble: 41,287 × 4
                  DATE    V1    V2    V3
                <dttm> <dbl> <dbl> <dbl>
1  2007-09-23 06:00:00  0.89  0.21  0.03
2  2007-09-23 06:10:00  NA    0.54  0.70
3  2007-09-23 06:20:00  0.74  0.22  0.80
4  2007-09-23 06:30:00  NA    0.48  0.38
5  2007-09-23 06:40:00  0.93  0.26  0.21

我只需要使用兩個data.frames就可以得到一個通用的解決方案。 我可以通過循環來完成,但是我敢打賭,這是一種更優雅的方式。 非常感謝高級!

對我來說,您要查找的內容還不是很清楚,但是根據示例輸出,您似乎希望保留TDF中V2V3的結果,而只刪除V1讀數。

一種方法是使用left_join沒有V1從柱TDF ,並只與V1從柱TDF2

left_join(
  select(TDF, -V1)
  , select(TDF2, DATE, V1) )

給出:

                  DATE    V2    V3    V1
                <dttm> <dbl> <dbl> <dbl>
1  2007-09-23 06:00:00  0.14  0.62    NA
2  2007-09-23 06:10:00  0.87  0.05  0.87
3  2007-09-23 06:20:00  0.20  0.52    NA
4  2007-09-23 06:30:00  0.34  0.01    NA
5  2007-09-23 06:40:00  0.92  0.37  0.83
6  2007-09-23 06:50:00  0.94  0.27    NA
7  2007-09-23 07:00:00  0.98  0.49    NA
8  2007-09-23 07:10:00  0.70  0.98    NA
9  2007-09-23 07:20:00  0.05  0.55  0.72
10 2007-09-23 07:30:00  0.16  0.12  0.99

從我的隨機數據中

如果您正在尋找更完整的解決方案,則可以執行full_join ,它將產生重復的列,然后根據需要對其進行處理。 例如,這將返回NAV1 ,如果TDF2$V1丟失,但對於V2V3它給TDF如果缺失值,並且只給出NA如果兩個值都存在不同。 由於我不確定您要使用什么,因此您可能需要在此處添加更復雜的檢查。

full_join(TDF, TDF2, "DATE") %>%
  mutate(V1 = ifelse(is.na(V1.y), NA, V1.x)
         , V2 = ifelse(is.na(V2.y), V2.x
                       , ifelse(V2.x == V2.y, V2.x, NA))
         , V3 = ifelse(is.na(V3.y), V3.x
                       , ifelse(V3.x == V3.y, V3.x, NA))
         )

返回值:

# A tibble: 41,287 × 10
                  DATE  V1.x  V2.x  V3.x  V1.y  V2.y  V3.y    V1    V2    V3
                <dttm> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1  2007-09-23 06:00:00  0.62  0.14  0.62    NA    NA    NA    NA  0.14  0.62
2  2007-09-23 06:10:00  0.87  0.87  0.05  0.87  0.87  0.05  0.87  0.87  0.05
3  2007-09-23 06:20:00  0.53  0.20  0.52    NA    NA    NA    NA  0.20  0.52
4  2007-09-23 06:30:00  0.03  0.34  0.01    NA    NA    NA    NA  0.34  0.01
5  2007-09-23 06:40:00  0.83  0.92  0.37  0.83  0.92  0.37  0.83  0.92  0.37
6  2007-09-23 06:50:00  0.70  0.94  0.27    NA    NA    NA    NA  0.94  0.27
7  2007-09-23 07:00:00  0.51  0.98  0.49    NA    NA    NA    NA  0.98  0.49
8  2007-09-23 07:10:00  0.65  0.70  0.98    NA    NA    NA    NA  0.70  0.98
9  2007-09-23 07:20:00  0.72  0.05  0.55  0.72  0.05  0.55  0.72  0.05  0.55
10 2007-09-23 07:30:00  0.99  0.16  0.12  0.99  0.16  0.12  0.99  0.16  0.12
# ... with 41,277 more rows

(並且,要清理重復的列,只需在完成后使用select即可。)

這是應該起作用的基本R解決方案:

is.na(TDF$V1[setdiff(seq_len(nrow(TDF)), match(TDF$Date, TDF2$Date))]) <- TRUE

match功能返回TDF2中存在相同日期的TDF中的觀察位置。 setdiff將此輸出轉換為該集合的補充,這是TDF中日期不匹配的觀察值集合。 對於這些觀察,使用is.na<-方法將TDF $ V1的值設置為NA。

暫無
暫無

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

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