Я могу использовать do.call
для поэлементного суммирования двух векторов:
do.call(what="+", args =list(c(0,0,1), c(1,2,3))
>[1] 1 2 4
Однако, если я хочу вызвать тот же оператор со списком из трех векторов, это не удастся:
do.call(what = "+", args = list(c(0,0,1), c(1,2,3), c(9,1,2)))
>Error in `+`(c(0, 0, 1), c(1, 2, 3), c(9, 1, 2)): operator needs one or two arguments
Я мог бы использовать Reduce
Reduce(f = "+", x = list(c(0,0,1), c(1,2,3), c(9,1,2)))
>[1] 10 3 6
, но я знаю о накладных расходах, генерируемых операцией Reduce
по сравнению с do.call
, а в моем РЕАЛЬНОМ приложении это недопустимо , поскольку мне нужно суммировать не трехэлементные списки, а скорее список из 10 ^ 5 элементов из 10 ^ 4-элементных векторов.
UPD: Reduce
оказался самым быстрым методом после все ...
lst <- list(1:10000, 10001:20000, 20001:30000)
lst2 <- lst[rep(seq.int(length(lst)), 1000)]
microbenchmark::microbenchmark(colSums(do.call(rbind, lst2)),
vapply(transpose(lst2), sum, 0),
Reduce(f = "+", x = lst2))
Unit: milliseconds
expr min lq mean median uq max neval cld
colSums(do.call(rbind, lst2)) 153.5086 194.9139 222.7954 198.1952 201.8152 915.6354 100 b
vapply(transpose(lst2), sum, 0) 398.9424 537.3834 732.4747 781.7255 813.7376 1538.4301 100 c
Reduce(f = "+", x = lst2) 101.5618 105.5864 139.8651 108.1204 112.7861 2567.1793 100 a