添加多个列表

时间:2015-12-07 12:59:51

标签: r

我将研究结果存储在列表中。

总共我有1000个列表,所有列表都是相同的维度。

每个列表包含39个不同维度矩阵的元素。

我想对这些列表求和,然后将它们除以1000.

我无法想办法做到这一点。

示例:

a<-matrix(0,nrow=5,ncol=6)
b<-matrix(0,nrow=2,ncol=10)

list1 <- list(a,b)

a<-matrix(0,nrow=5,ncol=6)
b<-matrix(0,nrow=2,ncol=10)

list2 <- list(a,b)

a<-matrix(0,nrow=5,ncol=6)
b<-matrix(0,nrow=2,ncol=10)

list3 <- list(a,b)

我想添加list1 + list2 + list3 ... list1000

然后将最终列表中的每个元素除以1000。

2 个答案:

答案 0 :(得分:3)

您可以结合使用MapReduce,并使用mget将所有列表收集到一个列表中。

a<-matrix(1,nrow=5,ncol=6)
b<-matrix(10,nrow=2,ncol=10)

list1 <- list(a,b)
list2 <- list(a,b)
list3 <- list(a,b)

l <- mget(ls(pattern = '^list\\d+$'))
(fl <- Reduce(function(x, y) Map(`+`, x, y), l))

# [[1]]
#      [,1] [,2] [,3] [,4] [,5] [,6]
# [1,]    3    3    3    3    3    3
# [2,]    3    3    3    3    3    3
# [3,]    3    3    3    3    3    3
# [4,]    3    3    3    3    3    3
# [5,]    3    3    3    3    3    3
# 
# [[2]]
#      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
# [1,]   30   30   30   30   30   30   30   30   30    30
# [2,]   30   30   30   30   30   30   30   30   30    30

Map(`/`, fl, 1000)

# [[1]]
#       [,1]  [,2]  [,3]  [,4]  [,5]  [,6]
# [1,] 0.003 0.003 0.003 0.003 0.003 0.003
# [2,] 0.003 0.003 0.003 0.003 0.003 0.003
# [3,] 0.003 0.003 0.003 0.003 0.003 0.003
# [4,] 0.003 0.003 0.003 0.003 0.003 0.003
# [5,] 0.003 0.003 0.003 0.003 0.003 0.003
# 
# [[2]]
#      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
# [1,] 0.03 0.03 0.03 0.03 0.03 0.03 0.03 0.03 0.03  0.03
# [2,] 0.03 0.03 0.03 0.03 0.03 0.03 0.03 0.03 0.03  0.03

答案 1 :(得分:0)

我最近为此实现了一些递归实用程序功能。但是他们没有检查前提条件(等长,元素的总结)。

编辑:我已修复了评论中提到的问题。 for循环由高阶函数替换,并且该函数具有更好的错误行为。该函数还处理更复杂的列表结构,例如列表包含其他包含数字元素的列表。它比OP要求的更多(也更复杂),但我认为值得保留,以防有人需要递归解决方案。

sum_numeric_lists <- function(...){
  lists <- list(...)

  if (length(unique(sapply(lists, length))) > 1) {
    stop("lists are not of equal length")
  }

  Map(function(...) {
    elems <- list(...)
    if (length(unique(sapply(elems, class))) > 1) {
      stop("corresponding elements have different types")
    }
    if (is.list(elems[[1]])) {
      sum_numeric_lists(...)
    } else if(is.numeric(elems[[1]])){
      Reduce(`+`, elems)
    } else {
      warning("lists contain types other than numeric, which are preserved as NULL elements")
      NULL
    }
  }, ...)

}


devide_numeric_list_by <- function(l, divisor){

  lapply(X = l, FUN = function(elem) {
    if (is.list(elem)) {
      devide_numeric_list_by(elem, divisor)
    } else if(is.numeric(elem)){
      elem / divisor
    } else {
      warning("lists contain types other than numeric, which are preserved as NULL elements")
      NULL
    }
  })

}

avg_numeric_lists <- function(...){
  sum_l <- sum_numeric_lists(...)
  devide_numeric_list_by(sum_l, length(list(...)))
}

一些测试:

avg_numeric_lists()
avg_numeric_lists(NULL)
avg_numeric_lists(list())
avg_numeric_lists(list(NULL))
avg_numeric_lists(list(1))
avg_numeric_lists(list(list(1)))

list1 <- list(m_first_lvl = matrix(sample(1:10, 20, replace = T), nrow=4, ncol=5),list(m_sec_lvl = matrix(sample(1:10, 6, replace = T), nrow=3, ncol=2)),"not_a_list_or_numeric",a_number = 1)
list2 <- list(m_first_lvl = matrix(sample(1:10, 20, replace = T), nrow=4, ncol=5),list(m_sec_lvl = matrix(sample(1:10, 6, replace = T), nrow=3, ncol=2)),"not_a_list_or_numeric",a_number = 2)
list3 <- list(m_first_lvl = matrix(sample(1:10, 20, replace = T), nrow=4, ncol=5),list(m_sec_lvl = matrix(sample(1:10, 6, replace = T), nrow=3, ncol=2)),"not_a_list_or_numeric",a_number = 3)
avg_numeric_lists(list1, list2, list3)

在全局环境中的所有列表上调用它(如rawr所示):

do.call(what = avg_numeric_lists, args = mget(ls(pattern = '^list\\d+$')))