【问题标题】:Lapply appending rows to matrix将行附加到矩阵
【发布时间】:2016-11-14 10:54:48
【问题描述】:

我很难在 lapply 循环中填充矩阵。

在我的数据中,我有一个包含 135 个地理空间点的列表。在 lapply 循环中,我根据这些站点坐标的 3 个不同半径内的景观计算各种指标。我想做的是循环遍历 135 个站点和 3 个半径的每个组合,然后用 (site,radius,metric1,metric2,metric3) 填充我的空白、预先准备好的矩阵的每一行。

我创建了一个简单的脚本来复制我遇到的问题。如果我可以像在here 中那样应用do.call(rbind, absdf) 命令,那么我还没有弄清楚如何......

# Generate empty matrix:
mymatrix <- matrix(,nrow=18, ncol=5)

# A vector with length of x (in my data this is the list of 135 sites):
a <- 1:6
#These sets will represent my metrics 
b <- rnorm(6, 5, 10)
c <- rnorm(6, 100, 20)
d <- rnorm(6, 20, 20)

# Radius vector:
rad <- c(100,200,300)

# The loop: lapply for site within lapply for radius
lapply(1:3,function(r){
  lapply(1:6,function(x){
  row.number <- (r-1)*6+x 
  tmpvector <- c(a[x], b[x], c[x], d[x], rad[r])
  mymatrix[row.number,] <- tmpvector
  })
})
View(mymatrix)

使用现在编写的代码,生成的矩阵仍然是空白的。

如果我把这个简单的例子写成一个 for 循环

mymatrix <- matrix(,nrow=18, ncol=5)

a <- 1:6
b <- rnorm(6, 5, 10)
c <- rnorm(6, 100, 20)
d <- rnorm(6, 20, 20)

rad <- c(100,200,300)

for (r in 1:3) {
  for (x in 1:6) {
    row.number <- (r-1)*6+x 
    tmpvector <- c(a[x], b[x], c[x], d[x], rad[r])
    mymatrix[row.number,] <- tmpvector
  }
} 
View(mymatrix)

然后矩阵会按照我的预期填充值。如果我犯了一个简单的错误,我深表歉意:我对这些循环很陌生!

注意,我也愿意创建这些数据的连续列表,然后我可以将其转换为更有用的格式!

【问题讨论】:

    标签: r matrix row lapply


    【解决方案1】:

    在这种情况下使用lapply 不是很自然。您根本不需要循环来创建这样的矩阵,您可以使用 R 的回收特性。

    mymatrix <- cbind(a, b, c, d, rep(c(100,200,300), each = 6))
    

    【讨论】:

    • 在我的示例中,确实不需要 lapply 来创建矩阵。但是,对于我的完整脚本中的迭代地理空间处理任务,lapply 是必需的,这些任务正在生成我必须组织成数据框或矩阵的输出。老实说,创建​​一个列表对我来说也足够了,因为我可以将该列表转换为更有用的格式。感谢您的建议,@Edwin!
    【解决方案2】:

    如果你真的想用lapply 来做这件事,这里有一个非常丑陋的方法(而且你自己也快到了):

    set.seed(123)
    #we don't really need to initialise the matrix anymore
    #mymatrix <- matrix(,nrow=18, ncol=5)
    
    a <- 1:6
    b <- rnorm(6, 5, 10)
    c <- rnorm(6, 100, 20)
    d <- rnorm(6, 20, 20)
    rad <- c(100,200,300)
    
    #Generate the list of rows:
    rowList<-lapply(1:3,function(r){
                        lapply(1:6,function(x){
                                   #data processing
                                   #row.number <- (r-1)*6+x #actually this line is unnecessary
                                   tmpvector <- c(a[x], b[x], c[x], d[x], rad[r])
                        })
    })
    
    #creation of mymatrix -- method 1
    mymatrix<-as.matrix(data.frame(rowList))
    colnames(mymatrix)<-NULL #since you probably don't want the ugly output
    mymatrix<-t(mymatrix)   
    
    ###   OR 
    #creation of my matrix -- method2 (with do.call and rbind)
    do.call(rbind,sapply(rowList,matrix))
    

    您的初始方法的问题(即尝试更改lapply 内的矩阵)是在每次迭代结束时您返回您创建的最后一个结果:当前行的创建以及没有创建错误、消息或警告,您没有任何输出。

    mymatrix 保持在 lapply 循环之前的状态,因为所有处理都在 {} 内部完成并且也没有保存。

    顺便说一句,如果你想对 lapply 的输出做任何事情,你应该将它们保存在一个对象中(或将它们直接插入另一个函数,如果你对内部逻辑不满意,我不会推荐应用)。

    希望我的解释不是太复杂而且有点离题,但是从 *apply 家族和等价物开始的好地方:R Grouping functions: sapply vs. lapply vs. apply. vs. tapply vs. by vs. aggregate

    【讨论】:

      猜你喜欢
      • 2015-10-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-05
      • 1970-01-01
      相关资源
      最近更新 更多