объединить наборы данных и добавить 0 строк для отсутствующих данных из других наборов данных в r

#r #merge

#r #объединить

Вопрос:

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

  dt1
 
 group   type  count
 1       cat   5
 1       dog   3
 1       bird  6

 dt2
 
 group   type  count
 2       cat   2
 2       dog   2
 2       rat   3

 dt3

 group   type  count
 3       fish  1
 3       dog   2
 3       rat   2
 

Я хочу объединить их таким образом, чтобы результат был:

  group   type  count
 1       cat   5
 1       dog   3
 1       bird  6
 1       rat   0
 1       fish  0
 2       cat   2
 2       dog   2
 2       rat   3
 2       fish  0
 2       bird  0
 3       fish  1
 3       dog   2
 3       rat   2
 3       cat   0
 3       bird  0
 

если я использую rbind(dt1, dt, dt3), я могу легко объединить их, но я не уверен, как добавить строки со счетом 0

Ответ №1:

Вы могли бы использовать bind_rows complete :

 dplyr::bind_rows(dt1, dt2, dt3) %>%
  tidyr::complete(group, type, fill = list(count = 0))

#   group type  count
#   <int> <chr> <dbl>
# 1     1 bird      6
# 2     1 cat       5
# 3     1 dog       3
# 4     1 fish      0
# 5     1 rat       0
# 6     2 bird      0
# 7     2 cat       2
# 8     2 dog       2
# 9     2 fish      0
#10     2 rat       3
#11     3 bird      0
#12     3 cat       0
#13     3 dog       2
#14     3 fish      1
#15     3 rat       2
 

Если таких фреймов данных много, и вы не можете вручную bind_rows(dt1, dt2, dt3) использовать их bind_rows(mget(paste0('dt', 1:3))) вместо этого.

Ответ №2:

Используя reduce merge подход.

 dtl <- list(dt1, dt2, dt3)
alltype <- unique(unlist(sapply(dtl, `[`, "type")))
Reduce(function(...) merge(..., all=TRUE), lapply(seq(dtl), function(x) {
  rbind(dtl[[x]],
        data.frame(group=x, type=setdiff(alltype, unique(dtl[[x]]$type)), count=0))
}))   
#    group type count
# 1      1 bird     6
# 2      1  cat     5
# 3      1  dog     3
# 4      1 fish     0
# 5      1  rat     0
# 6      2 bird     0
# 7      2  cat     2
# 8      2  dog     2
# 9      2 fish     0
# 10     2  rat     3
# 11     3 bird     0
# 12     3  cat     0
# 13     3  dog     2
# 14     3 fish     1
# 15     3  rat     2
 

Данные

 dt1 <- structure(list(group = c(1L, 1L, 1L), type = c("cat", "dog", 
"bird"), count = c(5L, 3L, 6L)), class = "data.frame", row.names = c(NA, 
-3L))
dt2 <- structure(list(group = c(2L, 2L, 2L), type = c("cat", "dog", 
"rat"), count = c(2L, 2L, 3L)), class = "data.frame", row.names = c(NA, 
-3L))
dt3 <- structure(list(group = c(3L, 3L, 3L), type = c("fish", "dog", 
"rat"), count = c(1L, 2L, 2L)), class = "data.frame", row.names = c(NA, 
-3L))