2016-08-08 82 views
0

我目前有一個雙重循環,根據給定數量的行和列將列表中的對象打印到網格中。我的問題是,我想爲用戶提供一個「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] 
} 

編輯:

道歉我應該這更明確強調。上面的代碼是我的實際代碼的高度簡化版本。主要列表是列表的列表,我使用的功能而不是文本沒有矢量化,因此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) 

我仍然有興趣,看看是否有這樣做的更好的辦法儘管如此。

+1

我可能會錯過一些東西,但是你是否正在嘗試編寫一個低效率的矩陣函數? – Roland

+0

「*我仍然有興趣看看是否還有更好的方法來做這件事。*」爲了有效地工作,我認爲我們需要看到一個更接近實際數據的例子。也許在一個新問題上,不要在這裏過多地移動球門柱。 – Gregor

回答

0

這裏的主要想法是通過x值或y值來訂購coords矩陣,然後將文本標籤添加到矩陣中。

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) 
}) 
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也有它自己的警告,如果行數和列數又不是不工作了 - 但如果它可以循環均勻地將默默填寫,所以你的警告可能是可取的。

+0

嗨,謝謝你的回覆@Gregor。不幸的是,這在我的特殊情況下不起作用。我的列表是列表的列表,我使用的功能未經過嚴格審覈。在原始問題中,我應該更加明確地表達歉意。我提供的示例代碼是該問題的一個非常簡化的版本。 – CroGo

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)