【问题标题】:R loop over multiple matricesR循环多个矩阵
【发布时间】:2014-10-02 20:36:10
【问题描述】:

我有 472 个矩阵,每个矩阵有 405 列(matrix1,...,matrix400),并且希望有 472 个新矩阵,其中只有该矩阵的前 244 列。我怎样才能做到这一点?我试过了:

for (i in 1:472) {
assign(paste("new_matrix",i,sep=""), matrix[[i]][,c(1:244)])
}

我通过用一个标识符(对于组)拆分一个数据帧来创建矩阵:

for (i in 1:472){
   assign(paste("matrix", i, sep=""), subset(data, ID==i))
}

不知何故,我无法对每个矩阵说话,但我不知道如何做到这一点。

【问题讨论】:

  • 我无法完全理解您的问题。列表中有所有这些矩阵吗?
  • 不,它们是单个矩阵,但它们的名称是 matrix1、matrix2、matrix3 等。这有帮助吗?
  • 好吧,如果你没有清单,你应该。在 R 中拥有一堆像这样的单个变量名是低效的,尤其是当你想对它们都执行类似的操作时。您应该很少需要在 R 中使用 get()/assign(),尤其是如果您是 R 新手。这通常表明您没有以“R 方式”做事。您是如何创建所有这些变量的?
  • 以如此无组织的方式拥有所有这些矩阵很奇怪。这是真正的问题。之后,就有可能找到解决方法...
  • 请看看我是如何得到这些矩阵的,已经感谢您的大力支持!

标签: r loops matrix


【解决方案1】:

您显然应该采取不同的方法。分配所有个人 矩阵是不是一个好方法。但这里有一种方法可以做到这一点......

mat1 <- matrix(1:6, 2, 3)
mat2 <- matrix(2:7, 2, 3)

example_func <- function(mati) {

  mat_name <- as.name(paste0("mat", mati))
  bquote(.(mat_name) <- .(mat_name)[ , 1:2])

}

for (i in 1:2) eval(example_func(i))

但是,使用eval 可能会很复杂,因为您必须非常小心环境,尤其是在函数中使用时。例如,尝试运行 lapply(1:2, function(x) eval(example_func(x))) 而不是使用 for 循环,看看结果有何不同。

要采取更好的方法,请查看?split

some_data <- data.frame(ID = rep(1:4, each = 4),
                        V1 = 1:16,
                        v2 = letters[1:16])

split(some_data, list(some_data$ID))

然后您可以使用lapply 来遍历您的子集和子集。或者,更好的是,只需先将原始 data.frame 子集到您想要的列,然后使用 split

【讨论】:

    【解决方案2】:
    matrix1 <- matrix(1:25, 5,5)
    matrix2 <- matrix(26:50, 5,5)
    

    假设,我想对上述矩阵的前 3 列进行子集化,

    list2env(
       setNames(
              lapply(mget(ls(pattern="matrix")), `[`, ,1:3),
                      paste("new", ls(pattern="matrix"),sep="_")), 
                                                   envir=.GlobalEnv)
    
      new_matrix1
      #     [,1] [,2] [,3]
      #[1,]    1    6   11
      #[2,]    2    7   12
      #[3,]    3    8   13
      #[4,]    4    9   14
      #[5,]    5   10   15
    
      new_matrix2
      #      [,1] [,2] [,3]
      # [1,]   26   31   36
      # [2,]   27   32   37
      # [3,]   28   33   38
      # [4,]   29   34   39
      # [5,]   30   35   40
    
    • ls(pattern="matrix") 将输出 [1] "matrix1" "matrix2"
    • mget 获取上述矩阵中存储的值作为列表
    • 使用lapply(...,[,1:3) 对列表中的前 3 列矩阵进行子集化
    • 使用setNamespaste 将列表元素的名称从matrix1matrix2 更改
    • 使用list2env 创建新对象new_matrix1new_matrix2。但是,在您的情况下,这将在全局环境中创建 472 new_matrices。我宁愿对列表中的矩阵进行子集化,以便在列表中进行所有必要的计算。然后您可以使用library(MASS) 中的write.tablewrite.matrix 将列表元素写入文件。

    【讨论】:

    • 我没有看到您的解决方案,并且已经将“开始”分配给了 dayne。对不起!谢谢,它也会起作用的!
    【解决方案3】:

    如果您从数据框开始

    以下是如何以按组(并具有其名称)和所需行数分割的矩阵列表结束:

    library("ddply")
    dlply(iris, .(Species), function(x) x[1:10,])
    

    iris 是一个带有基础 R 的虚拟数据框; 物种是你的因素组

    【讨论】: