【问题标题】:Loop over elements in vector, and elements are matrices循环遍历vector中的元素,元素是矩阵
【发布时间】:2017-05-28 04:36:20
【问题描述】:

我今天开始使用 R,如果这太基础了,我深表歉意。

首先我构造了 2 个矩阵,并构造了一个向量,其条目就是这些矩阵。然后,我尝试遍历向量的元素,即矩阵。但是,当我这样做时,我会收到“长度为零的参数”错误。

cam <- 1:12
ped <- 13:24

dim(cam) <- c(3,4)
dim(ped) <- c(4,3)

mats <- c('cam','ped')

for (i in  1:2) {
  rownames(mats[i]) <- LETTERS[1:dim(mats[i])[1]]
  colnames(mats[i]) <- LETTERS[1:dim(mats[i])[2]]
}

错误文字如下:

Error in 1:dim(mats[i])[1] : argument of length 0

问题:如何遍历向量的元素,这些元素是矩阵? (我猜我没有正确调用元素)。谢谢你的耐心。

【问题讨论】:

    标签: r loops vectorization


    【解决方案1】:

    R 中的首选选项是使用列表:

    cam <- 1:12 ; dim(cam) <- c(3,4)
    # same as matrix(1:12, nrow = 3, ncol = 4)
    ped <- 13:24 ; dim(ped) <- c(4,3)
    
    # save the list ( '=' sign for naming purposes only here)
    mats <- list(cam = cam, ped = ped)
    
    # notice the double brackets '[[' which is used for picking the list
    for (i in  1:length(mats) {
      rownames(mats[[i]]) <- LETTERS[1:dim(mats[[i]])[1]]
      colnames(mats[[i]]) <- LETTERS[1:dim(mats[[i]])[2]]
    }
    
    # finally you can call the whole list at once as follows:
    mats
    # or seperately using $ or [[
    mats$cam # mats[['cam']]
    mats$ped # mats[['ped']]
    

    交替

    如果你真的想发疯,你可以利用get()assign() 函数。 get() 按字符调用对象,assign() 可以创建一个。

    mats <- c('cam','ped')
    mats.new <- NULL # initialize a matrix placeholder
    for (i in  1:length(mats)) {
      mats.new <- get(mats[i]) # save as a new matrix each loop
      # use dimnames with a list input to do both the row and column at once
      dimnames(mats.new) <- list(LETTERS[1:dim(mats.new)[1]],
                                 LETTERS[1:dim(mats.new)[2]]) 
      assign(mats[i],mats.new) # create (re-write) the matrix
    }
    

    【讨论】:

    • 你为什么还要解释分配/获取?没有人应该使用它,尤其是新手。
    【解决方案2】:

    如果数据集放在list 中,我们可以使用lapply

    lst <- lapply(mget(mats), function(x) {
             dimnames(x) <-  list(LETTERS[seq_len(nrow(x))], LETTERS[seq_len(ncol(x))])
        x})
    

    最好将其保存在list 中。如果需要更改原始对象

    list2env(lst, envir = .GlobalEnv)
    

    【讨论】: