Как сделать конкретную сложную привязку двух таблиц

#r #dataframe #binding

#r #фрейм данных #привязка

Вопрос:

У меня есть фрейм данных с одним столбцом со всеми возможными идентификаторами:

 comment       ID 
 used         a1
 used         a2
 used         b1
 not_used     b11
 not_used     c1
 

Я получаю фрейм данных из своей базы данных с тем же столбцом «ID». Но в этом фрейме данных могут быть не все идентификаторы. Вот пример этой таблицы:

 ID    value
a1     18
a2     10
b1     10
 

Я хочу связать эти таблицы tw таким образом, чтобы идентификаторы, которых не было в моей таблице, имели нулевое значение. А также я хочу соответствующим образом сохранить комментарий к столбцу. Итак, как связать эти две таблицы, чтобы получить это:

 
comment       ID    value
 used         a1     18
 used         a2     10
 used         b1     10
 not_used     b11    0
 not_used     c1     0
 

Ответ №1:

Попробуйте это с помощью full_join() from dplyr и обманите NA with replace() :

 library(dplyr)
#Code
new <- df1 %>% full_join(df2) %>%
  replace(is.na(.),0)
 

Вывод:

    comment  ID value
1     used  a1    18
2     used  a2    10
3     used  b1    10
4 not_used b11     0
5 not_used  c1     0
 

Некоторые используемые данные:

 #Data1
df1 <- structure(list(comment = c("used", "used", "used", "not_used", 
"not_used"), ID = c("a1", "a2", "b1", "b11", "c1")), class = "data.frame", row.names = c(NA, 
-5L))

#Data2
df2 <- structure(list(ID = c("a1", "a2", "b1"), value = c(18L, 10L, 
10L)), class = "data.frame", row.names = c(NA, -3L))
 

Ответ №2:

Мы можем использовать merge из base R

 transform(merge(df1, df2, by = 'ID', all = TRUE),
      value = replace(value, is.na(value), 0))
 

-вывод

 #   ID  comment value
#1  a1     used    18
#2  a2     used    10
#3  b1     used    10
#4 b11 not_used     0
#5  c1 not_used     0
 

данные

 df1 <- structure(list(comment = c("used", "used", "used", "not_used", 
"not_used"), ID = c("a1", "a2", "b1", "b11", "c1")), class = "data.frame", 
row.names = c(NA, 
-5L))


df2 <- structure(list(ID = c("a1", "a2", "b1"), value = c(18L, 10L, 
10L)), class = "data.frame", row.names = c(NA, -3L))
 

Ответ №3:

Эта задача может быть решена с помощью библиотеки data.table.

 library(data.table) #import library
setDT(df1) #Set data.table structure to dataset
setDT(df2) #Set data.table structure to dataset
merge.data.table(df1, df2, by = c('ID'), all = TRUE)
# inner join to get only result that match both datasets