R: summarize items in multiple lists of different lengths?

I have the following lists:

l1 <- list(a = 3, b = 4, c = 8, d = 1)

l2 <- list(a = 3, b = 2, c = 5, d = 1, f = 4, g = 13)

How to combine both lists by summing the elements in both lists based on their names, like:

l1 + l2 = list(a=6, b=6, c=13, d=2, f=4, g=13)
+4
source share
3 answers

One of the options: meltand listto data.frame merge, enter them rowSumsin the numeric columns and go back to list.

library(reshape2)
d1 <- merge(melt(l1), melt(l2), by='L1', all=TRUE)
setNames(as.list(rowSums(d1[-1], na.rm=TRUE)), d1$L1)
#$a
#[1] 6

#$b
#[1] 6

#$c
#[1] 13

#$d
#[1] 2

#$f
#[1] 4

#$g
#[1] 13

Or we create unique namesboth 'l1' and 'l2' ('nm1'). Set loop "nm1", replaceNULL elements with 0 and execute +.

 nm1 <- union(names(l1), names(l2))
 lapply(nm1, function(x) {v1 <- l1[[x]]
                          v2 <- l2[[x]]
                         replace(v1, is.null(v1), 0) +
                         replace(v2, is.null(v2), 0)    

     })
+3
source

You can approach it using dplyras follows:

l1 <- list(a = 3, b = 4, c = 8, d = 1)
l2 <- list(a = 3, b = 2, c = 5, d = 1, f = 4, g = 13)

library(dplyr)

bind_rows(lapply(list(l1, l2), as.data.frame)) %>%
colSums(na.rm=TRUE) %>%
as.list()
+3
source

A slightly different approach

l1 <- list(a = 3, b = 4, c = 8, d = 1)
l2 <- list(a = 3, b = 2, c = 5, d = 1, f = 4, g = 13)
a <- l1[intersect(names(l1), names(l2))] 
b <- l2[intersect(names(l1), names(l2))]
ab <- as.numeric(a) + as.numeric(b)

c <- as.numeric(l1[!(l1 %in% a)])
d <- as.numeric(l2[!(l2 %in% b)])

c(ab, c, d)
# [1]  6  6 13  2  4 13
0
source

Source: https://habr.com/ru/post/1606803/


All Articles