Суммируйте каждый список числовых значений в списке
Я хотел бы прикрепить значения к меткам на речном участке в R
У меня есть список списков значений, который требуется для отображения потоков между узлами, например:
edges <- list( A= list( C= 10, E= 5 ),
B= list( C= 10 ),
C=list(D = 13, E = 7 ))
Мне известна функция, которая бы уменьшала (или суммировала) один элемент списка, например так: Reduce("+", ребра $A)
Есть ли способ сократить такой список списков значений до фрейма данных или чтобы я мог получить суммы:
Node Sum
A 15
B 10
C 20
D 13
E 12
Редактировать:
Я только что понял, что есть путаница: похоже, мне нужны два выхода, и это может быть немного сложнее: 1. если в списке "ребер" есть подсписок с именем категории, суммируйте 2. если нет, получите сумму все случаи этого предмета
Случай 1: Категории A, B, C (это начальные узлы) Случай 2: Категории D, E (это конечные узлы в речном участке)
Я прошу прощения за путаницу.
4 ответа
Я думаю, что вы можете сделать
lapply(edges, function (x) sum(unlist(x)))
Это возвращает список. С помощью sapply
упростит результат до вектора.
Мы также можем использовать base R
v1 <- unlist(edges)
tapply(v1, sub("\\..*", "", names(v1)), sum)
# A B C
#15 10 20
Или за один шаг
r1 <- tapply(unlist(edges), rep(names(edges), lengths(edges)), FUN = sum)
r1
# A B C
#15 10 20
если нам нужно sum
на основе names
после .
r2 <- tapply(v1, sub("[^.]+\\.", "", names(v1)), FUN = sum)
r2
# C D E
#20 13 12
c(r1, r2)[!duplicated(c(names(r1), names(r2)))]
# A B C D E
#15 10 20 13 12
Или используя aggregate/stack
aggregate(values~., stack(edges), FUN = sum)
# ind values
#1 A 15
#2 B 10
#3 C 20
Или используя свой предложенный Reduce
функция:
unlist(lapply(edges, function(a) Reduce(sum, a)))
# A B C
#15 10 20
Другой вариант заключается в использовании purrr
пакет:
library(purrr)
stack(map(edges, compose(sum, unlist)))
# values ind
# 1 15 A
# 2 10 B
# 3 20 C
где compose(sum, unlist)
эквивалентно function(x) sum(unlist(x))
,