【问题标题】:loop to create several matrix in R (maybe using paste)循环在 R 中创建多个矩阵(可能使用粘贴)
【发布时间】:2011-06-21 01:31:31
【问题描述】:

我想创建 27 个 2 列和可变行数的矩阵。 我可以只写 27 行代码,如下所示:

 x1 = cbind(rep(1,34), rnorm(34))

 x2 = cbind(rep(1,36), rnorm(36))

....

x27 = cbind(rep(1,k), rnorm(k))

但它必须有更好的方法来做到这一点。我想到了一个循环,像这样:

aux = c(34, 36, ..., k) # auxiliar variable with number of rows for each matrix

for (i in 1:27) paste("x",i, sep="") =  cbind(rep(1,aux[i]), rnorm(aux[i]))

但是,它不起作用。我觉得这是一项简单的任务,但我没有想法。

有什么帮助吗?

ps.:我想到了一个数组,但我无法使用它。也许一个列表可以完成这项工作,我不知道。

【问题讨论】:

  • 创建 27 个 R 对象(x1、x2、x3、...、x27)对我来说很重要
  • 寻找@Joshua Ulrich 的回答,因为我觉得我可能误解了你的问题。如果您需要不同的矩阵并且不连接到列表,那么绿色复选标记应该给他。
  • 两种解决方案都可以。谢谢大家,我标记了您的 (@daroczig) 答案,因为它对我有用。

标签: r loops matrix paste


【解决方案1】:

如果您需要不同的行数,那么您肯定需要使用列表。请看下面的例子:

首先,声明您的 aux 变量,该变量包含要生成的行数:

aux <- 50:77

让你的循环旋转:

x <- vector("list",27) 
for (i in 1:27) {
    x[[i]] <- cbind(rep(1,aux[i]), rnorm(aux[i]))
}

这将返回您的数据框列表。参见例如str(x) 用于列表,str(x[[1]]) 用于第一个矩阵的结构。后者将返回:

 num [1:50, 1:2] 1 1 1 1 1 1 1 1 1 1 ...

你是对的:它可以比这个提议写得更好,寻找lapply 等等,但其他人会帮助你解决这个棘手的部分:)


编辑后:添加lapply示例

如果您熟悉上述循环,请尝试以下代码(当然还要查找?lapply):

aux <- 50:77
fun <- function(x) cbind(rep(1,x), rnorm(x))
x <- lapply(aux, fun)

【讨论】:

  • 但是你不是必须先创建 x 吗?像 x
  • 是的,我们需要先创建 x 。非常感谢。我只使用了 x
  • @Manoel Galdino:是的,很抱歉这个错误!我已经编辑了我的答案并添加了额外的行,还添加了一个带有lapply 的示例,以使解决方案更整洁:)
  • 预分配!在循环之前定义x &lt;- vector("list",27),然后在循环内设置x 的每个元素。这比为每次迭代扩展列表要高效得多。
  • @Joshua Ulrich:是的,谢谢你的指出——这真的很有用。我已经编辑了我的答案以使其更好。而且我刚刚(在阅读了您的回答后)意识到我也可能误解了这个问题:(
【解决方案2】:

你需要assign:

for (i in 1:27) {
  assign(paste("x",i,sep=""), cbind(rep(1,aux[i]), rnorm(aux[i])))
}

这将在您的全局环境中创建 27 个矩阵对象。

【讨论】:

    【解决方案3】:

    如果您对列表没有任何意见,这里是您的另一个问题:

    aux <- 30:40
    manoel <- sapply(aux, function(x) {
                matrix(NA, ncol = 2, nrow = x)
            }, simplify = FALSE)
    
    > str(manoel)
    List of 11
     $ : logi [1:30, 1:2] NA NA NA NA NA NA ...
     $ : logi [1:31, 1:2] NA NA NA NA NA NA ...
     $ : logi [1:32, 1:2] NA NA NA NA NA NA ...
     $ : logi [1:33, 1:2] NA NA NA NA NA NA ...
     $ : logi [1:34, 1:2] NA NA NA NA NA NA ...
     $ : logi [1:35, 1:2] NA NA NA NA NA NA ...
     $ : logi [1:36, 1:2] NA NA NA NA NA NA ...
     $ : logi [1:37, 1:2] NA NA NA NA NA NA ...
     $ : logi [1:38, 1:2] NA NA NA NA NA NA ...
     $ : logi [1:39, 1:2] NA NA NA NA NA NA ...
     $ : logi [1:40, 1:2] NA NA NA NA NA NA ...
    

    【讨论】:

      【解决方案4】:

      下面的代码展示了我如何使用 Joshua Ulrich 的方法来创建稍微复杂一些的矩阵。希望这个答案有助于展示创建对象的一些可能的灵活性。如果没有,我可以删除我的答案。

      我怀疑这种方法可以很容易地修改以创建大小不同的矩阵,例如,通过将nrowncol 设置为等于一个变量,并使用rep(q, z) 和一些变量z 来复制其中的元素matrixrbind 语句中的向量:

      p1.c1 <- 0.10
      p2.c1 <- 0.20
      p3.c1 <- 0.30
      p4.c1 <- 0.40
      
      s1.c1  <- matrix(c(p1.c1, p1.c1, (1 - p1.c1),
                         p1.c1, p1.c1, (1 - p1.c1),
                             0,     0,          1), nrow=3, ncol=3, byrow = TRUE)
      s2.c1  <- matrix(c(p2.c1, p2.c1, (1 - p2.c1),
                         p2.c1, p2.c1, (1 - p2.c1),
                             0,     0,          1), nrow=3, ncol=3, byrow = TRUE)
      s3.c1  <- matrix(c(p3.c1, p3.c1, (1 - p3.c1),
                         p3.c1, p3.c1, (1 - p3.c1),
                             0,     0,          1), nrow=3, ncol=3, byrow = TRUE)
      s4.c1  <- matrix(c(p4.c1, p4.c1, (1 - p4.c1),
                         p4.c1, p4.c1, (1 - p4.c1),
                             0,     0,          1), nrow=3, ncol=3, byrow = TRUE)
      
      n <- 5
      
      p.c1 <- c(p1.c1, p2.c1, p3.c1, p4.c1)
      
      for (i in 1: (n - 1)) {
        assign(paste('xs', i, '.c1', sep=""), matrix(c(p.c1[i], p.c1[i], (1-p.c1[i]),
                                                       p.c1[i], p.c1[i], (1-p.c1[i]),
                                                             0,       0,         1 ), nrow=3, ncol=3, byrow = TRUE))
      }
      identical(xs1.c1, s1.c1)
      identical(xs2.c1, s2.c1)
      identical(xs3.c1, s3.c1)
      identical(xs4.c1, s4.c1)
      
      for (i in 1: (n - 1)) {
        assign(paste('ys', i, '.c1', sep=""), rbind(c(p.c1[i], p.c1[i], (1-p.c1[i])),
                                                    c(p.c1[i], p.c1[i], (1-p.c1[i])),
                                                          c(0,       0,          1)))
      
      }
      identical(ys1.c1, s1.c1)
      identical(ys2.c1, s2.c1)
      identical(ys3.c1, s3.c1)
      identical(ys4.c1, s4.c1)
      

      【讨论】:

        猜你喜欢
        • 2021-03-25
        • 2014-09-03
        • 2015-06-12
        • 1970-01-01
        • 2014-10-02
        • 2017-11-22
        • 1970-01-01
        • 1970-01-01
        • 2018-05-31
        相关资源
        最近更新 更多