velvetrock
velvetrock

Reputation: 585

combine a list of data.frame by listid

I want to combine a list of data.frame by listId. Here is my data:

set.seed(1234)
test = list()
test[[1]] = list(id = data.frame(listId = 1:3, id = c("a", "b", "c")), name = data.frame(listId = 1:3, name = c("Julie", "Mac", "Eric")), score = data.frame(listId = c(rep(2, 4), rep(3, 6)), score = sample(1:20, 10)))
test[[2]] = list(id = data.frame(listId = 1:2, id = c("d", "e")), name = data.frame(listId = 1:2, name = c("Amy", "Lucy")), score = data.frame(listId = c(rep(1, 2), rep(2, 3)), score = sample(1:20, 5)))

Expected output:

# listId id  name score
# 1       1  a Julie    NA
# 2       2  b   Mac     3
# 3       2  b   Mac    12
# 4       2  b   Mac    11
# 5       2  b   Mac    18
# 6       3  c  Eric    14
# 7       3  c  Eric    10
# 8       3  c  Eric     1
# 9       3  c  Eric     4
# 10      3  c  Eric     8
# 11      3  c  Eric     6
# 12      1  d   Amy    14
# 13      1  d   Amy    11
# 14      2  e  Lucy     6
# 15      2  e  Lucy    16
# 16      2  e  Lucy     5

Upvotes: 2

Views: 36

Answers (1)

akrun
akrun

Reputation: 887078

We could use left_join by 'listId' after looping through the 'test' with map

library(dplyr)
library(purrr)
test %>% 
    map_df(~ .x %>% 
                reduce(left_join, by = 'listId'))
#   listId id  name score
#1       1  a Julie    NA
#2       2  b   Mac     3
#3       2  b   Mac    12
#4       2  b   Mac    11
#5       2  b   Mac    18
#6       3  c  Eric    14
#7       3  c  Eric    10
#8       3  c  Eric     1
#9       3  c  Eric     4
#10      3  c  Eric     8
#11      3  c  Eric     6
#12      1  d   Amy    14
#13      1  d   Amy    11
#14      2  e  Lucy     6
#15      2  e  Lucy    16
#16      2  e  Lucy     5

Or without using any packages

do.call(rbind, lapply(test, function(x) Reduce(function(...) 
                 merge(..., by = 'listId', all.x = TRUE), x)))

Upvotes: 2

Related Questions