2012-01-12 86 views
2

似乎每個涉及R中循環的問題都會遇到「循環不好」和「你做錯了」的建議使用listtapply或什麼都不會。這是循環的有效實現嗎?

我學習R,並已實現了以下循環來創建映像文件每個因子的水平,因子水平每次換水的#我運行它:

for(i in unique(df$factor)) { 
    lnam <- paste("test_", i, sep="") 
    assign(lnam, subset(df, factor==i)) 
    lfile <- paste(lnam, ".png", sep="") 
    png(file = lfile, bg="transparent") 
     with(get(lnam), hist(x, main = paste("Histogram of x for ", i, " factor", sep=""))) 
    dev.off() 
} 

這工作。我想將它擴展到可能對這些子組(也輸出到文件)進行各種測試等。

這是循環的有效和合法使用嗎?或者有沒有一種首選的方法來剝皮這隻貓?

回答

7

循環通常沒有問題。有時候,特別是當您使用文件或調用函數來獲得副作用而不是輸出時,循環可能比*apply調用更容易遵循。但是,當您使用循環來模擬可以進行矢量化的操作時,它往往要慢得多,因此建議避免它們。

回覆您的具體的例子,不過,我想提出以下意見:

  • 如果你想要做的事的一個因素每一個級別,它更容易使用levels(factor)而非unique(factor)
  • 您不需要專門爲每個因子級別創建新的數據框。

考慮到這一點:

for(i in levels(df$factor)) 
{ 
    lf <- paste("test_", i, ".png", sep="") 
    png(file=lf, bg="transparent", 
     with(subset(df, factor == i), hist(x, ....) 
    dev.off() 
} 
+3

你也可以在循環之外使用'paste'函數。 – csgillespie 2012-01-12 08:12:03

+0

謝謝 - 簡化是有道理的。雖然我可能正在對製作的數據框架執行其他「魔術」...... @csgillespie您的評論讓我感到困惑 - 那麼您將如何命名該文件? – Trees4theForest 2012-01-12 08:19:42

+0

類似'lf = paste(「test_」,levels(df $ factor),「.png」,sep =「」'。當然,你需要改變'i'正在迭代的內容。在這種情況下,你下降的路線並沒有什麼區別。 – csgillespie 2012-01-12 08:24:37

4

在這種情況下,一個合理的選擇是使用split將數據幀轉換成數據幀的列表中,用特定因子水平每片含子。

split_df <- split(df, df$factor) 

科林提到,paste可以矢量化,所以你只需要調用它一次。

lfile <- paste("test_", names(split_df), ".png", sep = "") 

將所有繪圖代碼分組到一個函數中。

draw_and_save_histogram <- function(data, file) 
{ 
    png(file) 
    with(data, hist(x)) 
    dev.off() 
} 

現在,您可以更方便地比較一個普通的循環和*apply功能之間的差異(在這種情況下mapply,因爲我們需要兩個輸入)。

for(i in seq_along(split_df)) 
{ 
    draw_and_save_histogram(split_df[[i]], lfile[i]) 
} 

mapply(
    draw_and_save_histogram, 
    split_df,  
    lfile  
) 

而不是繪製大量直方圖被保存在不同的文件,它是更理想繪製一個情節與多家面板使用latticeggplot2

library(lattice) 
histogram(~ x | factor, df) 

library(ggplot2) 
ggplot(df, aes(x)) + geom_histogram() + facet_wrap(~ factor) 
+0

太好了,謝謝你的輸入。我並不知道'split' - 好的方法,至於它「更可取繪製一個繪圖」,我想這一切都取決於你的需要,我實際上是在循環中使用點陣,繪製一系列嵌套圖,需要在單獨的文件中輸入輸出,但對於認爲他們有同樣問題的人來說,這將是一個不錯的主角。 – Trees4theForest 2012-01-12 14:18:42