Как соединить только определенные строки с помощью dplyr? - PullRequest
1 голос
/ 08 июля 2020

Итак, у меня есть фрейм данных как таковой

ID     Date     TIME     var    Data     misc
1  1/3/2018  3:30 AM       a  string1  string1
1  4/23/2019 1:32 PM       b  string2  string1
1  1/3/2018  4:53 PM       c  string3  string1
2  1/4/2018  3:32 AM       d  string4  string2
2  3/3/2018  3:30 PM       s  string5  string2
2  3/3/2018  3:30 PM       e  string6  string2
3  4/23/2019 6:24 AM       w
3  4/23/2019 1:32 PM       s 
3  4/24/2019 3:20 PM       s
3  4/24/2019 3:20 PM       a

Есть ряд столбцов, похожих на Data и misc, к которым я хотел бы присоединиться, чтобы заполнить df, используя другой df, содержащий данных ID = 3.

ID3_data

     DATE    Time       Data       misc
4/23/2019 6:24 AM    string7    stringA
4/23/2019 1:32 PM    string8    stringB
4/24/2019 3:20 PM    string9    stringC
4/24/2019 3:20 PM   string10    stringC

Итак, как я мог покинуть свой DF с этим ID3_data только для строк, где ID =3?

Кроме того, есть еще одна проблема, когда единственный идентификатор, который у меня есть, это Date и TIME, но у меня есть разные совпадения с одними и теми же идентификаторами, есть ли способ сказать, что первый экземпляр идет к первому, а второй - ко второму ??? Короче говоря, окончательный DF должен выглядеть так:

ID     Date     TIME     var     Data       misc
1  1/3/2018  3:30 AM       a   string1    string1
1  4/23/2019 1:32 PM       b   string2    string1
1  1/3/2018  4:53 PM       c   string3    string1
2  1/4/2018  3:32 AM       d   string4    string2
2  3/3/2018  3:30 PM       s   string5    string2
2  3/3/2018  3:30 PM       e   string6    string2
3 4/23/2019  6:24 AM       w   string7    stringA
3 4/23/2019  1:32 PM       s   string8    stringB
3 4/24/2019  3:20 PM       s   string9    stringC
3 4/24/2019  3:20 PM       a  string10    stringC

Опять же, приоритетом является объединение выбранных строк, но если бы проблема с дублированием также могла быть выполнена в том же sw oop с использованием dplyr, это было бы здорово .

1 Ответ

2 голосов
/ 08 июля 2020

Мы могли бы выполнить соединение с помощью coalesce. Принимая пропущенные значения как NA

library(dplyr)# 1.0.0
left_join(DF, ID3_data %>%
           mutate(ID = 3), by = c('ID', 'Date' = 'DATE', 'TIME' = 'Time')) %>%
       mutate(Data = coalesce(Data.x, Data.y), misc = coalesce(misc.x, misc.y))

Или, если есть дубликаты, то можно связать строки двух наборов данных, а затем выполнить группировку по summarise только с строками, отличными от NA (dplyr 1.0.0 позволяет summarise с более чем одним строка)

cbind(ID = 3, ID3_data) %>%
   set_names(names(DF)) %>% 
  bind_rows(DF) %>%
  group_by(ID, Date, TIME) %>% 
  summarise(across(everything(), ~ .[!is.na(.)]))
# A tibble: 10 x 5
# Groups:   ID, Date, TIME [8]
#      ID Date      TIME    Data     misc   
#   <dbl> <chr>     <chr>   <chr>    <chr>  
# 1     1 1/3/2018  3:30 AM string1  string1
# 2     1 1/3/2018  4:53 PM string3  string1
# 3     1 4/23/2019 1:32 PM string2  string1
# 4     2 1/4/2018  3:32 AM string4  string2
# 5     2 3/3/2018  3:30 PM string5  string2
# 6     2 3/3/2018  3:30 PM string6  string2
# 7     3 4/23/2019 1:32 PM string8  stringB
# 8     3 4/23/2019 6:24 AM string7  stringA
# 9     3 4/24/2019 3:20 PM string9  stringC
#10     3 4/24/2019 3:20 PM string10 stringC

данные

DF <- structure(list(ID = c(1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L, 3L), 
    Date = c("1/3/2018", "4/23/2019", "1/3/2018", "1/4/2018", 
    "3/3/2018", "3/3/2018", "4/23/2019", "4/23/2019", "4/24/2019", 
    "4/24/2019"), TIME = c("3:30 AM", "1:32 PM", "4:53 PM", "3:32 AM", 
    "3:30 PM", "3:30 PM", "6:24 AM", "1:32 PM", "3:20 PM", "3:20 PM"
    ), Data = c("string1", "string2", "string3", "string4", "string5", 
    "string6", NA, NA, NA, NA), misc = c("string1", "string1", 
    "string1", "string2", "string2", "string2", NA, NA, NA, NA
    )), class = "data.frame", row.names = c(NA, -10L))
ID3_data <- structure(list(DATE = c("4/23/2019", "4/23/2019", "4/24/2019", 
"4/24/2019"), Time = c("6:24 AM", "1:32 PM", "3:20 PM", "3:20 PM"
), Data = c("string7", "string8", "string9", "string10"), misc = c("stringA", 
"stringB", "stringC", "stringC")), class = "data.frame",
row.names = c(NA, 
-4L))
...