Суммируйте каждый список числовых значений в списке

Я хотел бы прикрепить значения к меткам на речном участке в R

У меня есть список списков значений, который требуется для отображения потоков между узлами, например:

edges <- list( A= list( C= 10, E= 5 ), 
               B= list( C= 10 ), 
               C=list(D = 13, E = 7 )) 

Мне известна функция, которая уменьшает (или суммирует) один элемент списка, например: Reduce("+",edges$A)

Есть ли способ сократить такой список списков значений до фрейма данных или чтобы я мог получить суммы:

Node Sum
A 15
B 10
C 20
D 13
E 12 

Редактировать:

Я только что понял, что есть путаница: похоже, мне нужны два вывода, и это может быть немного сложнее: 1. если в списке «ребер» есть подсписок с именем категории, просуммируйте 2. если нет, получите сумму все вхождения этого элемента

Случай 1: Категории A, B, C (это начальные узлы) Случай 2: Категории D, E (это конечные узлы речного участка)

Прошу прощения за путаницу.


person Jacek Kotowski    schedule 27.06.2016    source источник
comment
Ваше редактирование не имеет особого смысла.   -  person akrun    schedule 27.06.2016
comment
Это может быть ... Я думаю об этом ... Я заметил, что unlist (ребра) дает мне A.C A.E B.C C.D C.E 10 5 10 13 7 Если бы я мог как-то суммировать только по категории после точки...   -  person Jacek Kotowski    schedule 27.06.2016
comment
Извините, я понял, что узлы D, E не будут суммироваться с помощью этого метода и, возможно, нужно другое решение. Это конечные узлы, и они не являются частью основного списка. Это элементы подсписков, которые необходимо суммировать. Я попытался описать свою правку и путаницу в основном вопросе.   -  person Jacek Kotowski    schedule 27.06.2016
comment
Я принял ответ. Я сам заслужил минус, ужасно извиняюсь, что не заметил вопроса.   -  person Jacek Kotowski    schedule 27.06.2016


Ответы (4)


Я думаю, ты можешь сделать

lapply(edges, function (x) sum(unlist(x)))

Это возвращает список. Использование sapply упростит результат до вектора.

person Zheyuan Li    schedule 27.06.2016
comment
Извините, я исправил свой вопрос. Я забыл о суммировании D и E. Я заметил, что unlist дает мне A.C A.E B.C C.D C.E 10 5 10 13 7 Если бы я мог как-то суммировать только по категории после точки... - person Jacek Kotowski; 27.06.2016

Мы также можем использовать 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
person akrun    schedule 27.06.2016
comment
Извините, я исправил свой вопрос. Я забыл о суммировании D и E. Я заметил, что unlist дает мне A.C A.E B.C C.D C.E 10 5 10 13 7 Если бы я мог как-то суммировать только по категории после точки... - person Jacek Kotowski; 27.06.2016
comment
@JacekKotowski В этом случае вы не получите категорию «А». Можете ли вы объяснить ожидаемый результат? - person akrun; 27.06.2016
comment
@ZheyuanLi Плюс один тебе. - person akrun; 27.06.2016
comment
@JacekKotowski Я обновил сообщение, чтобы получить ожидаемое, хотя я не уверен, что это за условие. - person akrun; 27.06.2016
comment
плюс один для stack. хорошая функция. - person 989; 27.06.2016

Другой вариант — использовать пакет 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)).

person Psidom    schedule 27.06.2016
comment
Извините, я исправил свой вопрос. Я забыл о суммировании D и E. Я заметил, что unlist дает мне A.C A.E B.C C.D C.E 10 5 10 13 7 Если бы я мог как-то суммировать только по категории после точки... - person Jacek Kotowski; 27.06.2016

Или используя предложенную вами функцию Reduce:

unlist(lapply(edges, function(a) Reduce(sum, a)))

# A  B  C 
#15 10 20 
person 989    schedule 27.06.2016