2011-06-22 79 views
22

我發現自己處於完成大量分析的位置,現在需要用略有不同的輸入假設來重複分析。重複大量分析的策略

在這種情況下,分析涉及聚類分析,繪製多個圖表,以及導出聚類ID和其他感興趣的變量。關鍵是它是一個廣泛的分析,需要重複和比較兩次。

我認爲:

  • 創建功能。這並不理想,因爲那時我必須修改我的代碼,以瞭解我是在函數還是父級環境中進行評估。這額外的努力似乎過度,使調試更困難,並可能引入副作用。
  • 將其包裝在for循環中。再次,不理想,因爲那樣我必須創建索引變量,這也會引入副作用。
  • 創建一些前導代碼,將分析包裝在一個單獨的文件中,並將它分解爲source。這很有效,但看起來非常難看,並且不理想。

分析的目標是完成一組對象(在列表或單獨的輸出文件中),以便我可以進一步分析差異。

處理這類問題的好策略是什麼?

回答

17

使代碼可重複使用需要一些時間,精力和持有一些額外的挑戰,比如你提到你自己。

是否投資的問題可能是信息學中的關鍵問題(如果不是其他許多領域):我是否編寫腳本以類似的方式重命名50個文件,或者我會繼續並手動將其重命名。

我相信,答案是非常個人化的,即便如此,也是不同的。如果你在編程上很容易,你可能會很快決定去使用重用路由,因爲你的努力會相對較低(即使這樣,程序員通常喜歡學習新的技巧,所以這是一個隱藏的,往往適得其反的動機)。

這就是說,在你的特定情況下:我會選擇採購方式:因爲你打算只重複使用代碼2次以上,所以更大的努力可能會浪費(你指出分析相當廣泛) 。那麼,如果它不是一個優雅的解決方案呢?沒有人會看到你這樣做,每個人都會對快速的結果感到滿意。

如果在一年左右發現再利用率高於預期,那麼您仍然可以投資。到那個時候,您還將有(至少)三種情況,您可以將重寫和時髦的可重複使用版本的結果與您當前的結果進行比較。

如果/當我知道前面我要重複使用代碼時,我會在開發它的同時記住這一點。無論哪種方式,我幾乎都不會編寫不在函數中的代碼(好吧,除了用於SO和其他開箱即用分析的兩行代碼):我發現這使我更容易構建自己的想法。

+0

+1因爲你只會再做兩次。答案還取決於你每次通過分析會有多少變化 - 只有幾個參數,輸入數據,?我發現(1)拉出關鍵參數並在代碼的頂部定義它們[或者將它們放在單獨的文件中,並將'source()'分析主體]和(2)在一個函數中包裝代碼的主體。我不清楚你的父母對功能環境的區別在哪裏。 –

+0

+1這是我最後做的。我將每次運行更改的所有參數都包裝到列表中。然後創建包含每次運行的輸入值的不同列表(具有相同的結構)。對於每次迭代,我複製必要的列表並將結果變量保存到輸出列表中。換句話說,將代碼封裝成序言和清理,並完成工作。有用。沒關係,如果它很醜陋... – Andrie

3

我喜歡在這些情況下使用一個小shell腳本,pdf裁剪程序和Sweave的組合。這會給你回報很好的報告,並鼓勵你來源。通常我使用幾個文件,就像創建一個包(至少我覺得它是這樣的:)。我有一個單獨的數據文件用於處理不同類型的分析數據,例如descriptiveStats.R,regressions.R。

順便說一句,這裏是我的小shell腳本,

#!/bin/sh 
R CMD Sweave docSweave.Rnw 
for file in `ls pdfs`; 
do pdfcrop pdfs/"$file" pdfs/"$file" 
done 
pdflatex docSweave.tex 
open docSweave.pdf 

的Sweave文件通常源在需要時上述R上的文件。我不確定這是否是你想要的,但這是我迄今爲止的策略。至少我相信創建透明,可重複的報告至少有助於遵循一種策略。

+0

+1我將不得不更多地探索shell腳本 - 我傾向於不使用它們。這與使用'source'似乎是等價的,或者至少是類似的。 – Andrie

+0

這一切都取決於操作系統。我還不確定python,shell腳本或蘋果腳本是否最適合我的需求,但據我判斷,用R編寫shell腳本看起來確實值得一看,特別是對於自動化報告。 –

10

如果可能,請在外部參數文件中設置不同的sets/runs/experiments參數。然後,您可以獲取代碼,調用一個函數,甚至可以使用一個包,但操作由一小組外部定義的參數確定。

例如,JSON對此非常有效,RJSONIOrjson包允許您將文件加載到列表中。假設你將它加載到名爲parametersNN.json的列表中。一個例子如下:

{ 
"Version": "20110701a", 
"Initialization": 
{ 
    "indices": [1,2,3,4,5,6,7,8,9,10], 
    "step_size": 0.05 
}, 
"Stopping": 
{ 
    "tolerance": 0.01, 
    "iterations": 100 
} 
} 

保存,作爲 「parameters01.json」 和負載爲:

library(RJSONIO) 
Params <- fromJSON("parameters.json") 

,你是關閉和運行。 (注意:我喜歡在我的參數文件中使用唯一的版本#,以便稍後可以識別集合,如果我正在查看R中的「參數」列表)。只需調用腳本並指向參數文件,例如:

Rscript --vanilla MyScript.R parameters01.json 

然後,在程序內,識別所述參數從commandArgs()功能文件。

稍後,您可以將代碼分解爲函數和包,但這可能是在短期​​內使vanilla腳本具有通用性的最簡單方法,並且它是長期的良好實踐,因爲代碼應該是分離的來自運行/數據集/實驗相關參數的規範。

編輯:更確切地說,我甚至會在JSON中指定輸入和輸出目錄或文件(或命名模式/前綴)。這很清楚一組參數如何導致一個特定的輸出集合。它們之間的所有內容都只是運行給定參數化的代碼,但代碼應該不會真的發生太大的變化,應該如何?


更新: 三個月,成千上萬的跑步,比我以前的答案懂事了,我想說的是,在JSON參數外部存儲是1-1000不同的運行非常有用。當參數或配置數量在千位及以上時,最好切換到使用數據庫進行配置管理。每種配置都可能源於JSON(或XML),但能夠應對不同的參數佈局需要更大規模的解決方案,對此類數據庫像SQLite(通過RSQLite)是一個很好的解決方案。我意識到這個答案對於原始問題是過度的 - 如何重複工作只需幾次,只需要進行一些參數修改,但是當在正在進行的研究中擴展數百或數千參數變化時,更多的工具是必要。 :)

+0

這對我來說是一個非常有用的答案。我甚至沒有去'JSON',而只是在配置目錄中使用了一個小的'.R'腳本。 Grid Engine設置一個環境變量,其中包含作業名稱,這樣我就可以讀取它並讓它爲該作業提取相同名稱的配置文件。適合我的需求;這聽起來像你的更實質! –

+1

@ AriB.Friedman很樂意幫忙!數據庫方法似乎在數千甚至更高的情況下運行良好。如果沒有別的辦法,可以將參數設置看作類似於實驗設計 - 將設計參數存儲在數據庫中可以擴展,最終我們想知道爲什麼不同的結果有不同的結果。 – Iterator

1

我傾向於將這樣的結果推入全局列表。 我使用Common Lisp,但是R沒有那麼不同。

+1

+1是的,這是我最後做的。創建一個需要改變的變量列表和另一個帶有結果的列表。然後切換本地變量進出列表。 – Andrie

1

這裏太晚了,但我使用Sweave很多,而且很可能我從一開始就使用了Sweave文件(例如,如果我知道最終產品需要某種報告)。

對於重複分析的部件的第二和第三時間,有那麼兩個選項:

  • 如果結果而「獨立的」(即,應產生3個報道,比較裝置的報告進行檢查並排的),並且改變後的輸入以新數據文件的形式出現,它們與Sweave文件的副本一起進入其自己的目錄,並創建單獨的報告(類似於源代碼,但對Sweave來說感覺更自然爲平原來源)。

  • 如果我寧願需要在一個Sweave文件中重複一次或兩次完全相同的事情,我會考慮重新使用代碼塊。這與醜陋的for-loop類似。

    原因是,當然結果是在一起進行比較,這將是報告的最後部分。

  • 如果從一開始就會清楚會有一些參數集和一個比較,我會用一種方式編寫代碼,只要我對分析的每個部分都很好,就會將它包裝到一個函數中(即,我在編輯器窗口中執行該功能,但在編寫函數時直接在工作區中評估這些行)。

既然你是在上面描述的情況,我同意尼克 - 沒有錯source,現在一切意味着更多的努力,你把它作爲已經腳本。

2

你的第三個選擇並不是那麼糟糕。我在很多情況下都這樣做。您可以通過將預先充足的代碼的結果放入環境中並添加一個您想要用於進一步分析的結構來構建更多結構。 一個例子:

setup1 <- local({ 
      x <- rnorm(50, mean=2.0) 
      y <- rnorm(50, mean=1.0) 
      environment() 
      # ... 
     }) 

    setup2 <- local({ 
      x <- rnorm(50, mean=1.8) 
      y <- rnorm(50, mean=1.5) 
      environment() 
      # ... 
     }) 

attach(setup1)和運行/源的分析代碼

plot(x, y) 
t.test(x, y, paired = T, var.equal = T) 
... 

完成後,detach(setup1)並附加第二個。

現在,至少您可以輕鬆地在設置之間切換。幫了我幾次。

+0

+1這種方法非常有趣。我通常儘量避免使用「attach」,但我喜歡創建環境來解決這個問題。我會進一步探索。 – Andrie

+0

我也喜歡這個,同樣謹慎的使用Andrie提到的'attach'。關於這一點的不錯之處在於它比參數列表更通用,並且可以包含計算。 – Iterator