如何反转双循环?

时间:2016-08-08 18:58:20

标签: r loops

我目前有一个双循环,它根据给定数量的行和列将列表中的对象打印到网格中。我的问题是我想为用户提供“byrow”选项,以便他们可以决定首先填充列或行。到目前为止我唯一能让它工作的方法是将代码加倍并改变循环顺序,这看起来非常低效。我的代码的简化版本如下。

如果需要更多信息,请告诉我。非常感谢任何帮助或指导。

plot ( x = 1:4 , y = 1:4 , type = "n")

w <- list ( "a" , "b" , "c" , "d" ,"e" , "f")

nrow <- 3 
ncol <- 2

if (length(w) > nrow * ncol ) warning("NOT ENOUGH rows/columns")


for ( i in 1:nrow) for (j in 1:ncol){
    if( !length(w) ) break
    text(i,j , w[[1]])
    w <- w[-1]
}

编辑:

道歉我应该更清楚地强调这一点。上面的代码是我实际代码的高度简化版本。主列表是一个列表列表,我使用的函数而不是text不会被矢量化,因此matrix对我的特定情况不起作用。

查看提供的答案,但我已设法使用其他人用来创建以下内容的revexpand.grid函数:

plot ( x = 1:4 , y = 1:4 , type = "n")

w <- list ( "a" , "b" , "c" , "d" ,"e" )

nrow <- 3 
ncol <- 2
byrow <- T

if (length(w) > nrow * ncol ) warning("NOT ENOUGH rows/columns")

grid <- expand.grid(1:nrow , 1:ncol) 
if ( !byrow) grid <- rev(grid)
grid <- grid[1:length(w),]

mapply( text , grid[,1] ,grid[,2] , w)

我仍然有兴趣看看是否还有更好的方法。

3 个答案:

答案 0 :(得分:3)

text()是矢量化的 - 并且可以很好地处理矩阵(已经有byrow个参数)。不需要循环。如果要将其切换,请将byrow更改为顶部的TRUE

byrow = FALSE

plot ( x = 1:4 , y = 1:4 , type = "n")
w <- list ( "a" , "b" , "c" , "d" ,"e" , "f") ## why a list, not a vector??

nrow <- 3 
ncol <- 2
if (length(w) > nrow * ncol ) warning("NOT ENOUGH rows/columns")

# no loop needed
mat = matrix(unlist(w), nrow = nrow, ncol = ncol, byrow = byrow)
text(x = expand.grid(1:nrow, 1:ncol), labels = mat)

matrix也有自己的警告,如果行和列号不能解决 - 但如果它可以均匀循环,它将默默地填写,所以你的警告可能更好。

答案 1 :(得分:1)

如@Gregor的this answer所示,对于您的简单示例,最好将matrix()text()的向量化功能结合使用,而不是使用双for循环

但是,如果实际生产代码的循环内部有更多内容,而不是最小的示例,这需要您使用双循环,那么您可以使用以下行中的某些循环来执行此操作:

w <- list ( "a" , "b" , "c" , "d" ,"e" , "f")
nrow <- 3 
ncol <- 2

f1 <- function(w, nrow, ncol, byrow=F) {
  if (length(w) > nrow * ncol ) warning("NOT ENOUGH rows/columns")
  size <- c(nrow,ncol)
  if (byrow) size <- rev(size) 
  for ( i in 1:size[1]) for (j in 1:size[2]){
    pos <- c(i,j)
    if (byrow) pos <- rev(pos)
    text(pos[1],pos[2] , w[[(i-1)*size[2]+j]]) 
  }
}

plot ( x = 1:4 , y = 1:4 , type = "n")
f1 (w, nrow, ncol, byrow=F) 

plot ( x = 1:4 , y = 1:4 , type = "n")
f1 (w, nrow, ncol, byrow=T) 

答案 2 :(得分:0)

此处的主要想法是按coords值或x值对y矩阵进行排序,然后将文本标签添加到矩阵中。

byrow <- TRUE
coords <- as.data.frame(expand.grid(1:nrow, 1:ncol))
names(coords) <- c("x","y")
if(!byrow) coords <- coords[order(coords[,"x"]),]
coords[["labels"]] <- unlist(w)
with(coords, {
  plot(x=1:4, y=1:4, type="n")
  text(x=x, y=y, labels=labels)
})