2014-03-28 75 views
2

我的論文數據採集過程涉及從各種開源軟件庫中提取數據,並將其保存爲[R對象供日後分析的對象。管理來自不同來源的

爲了防止已處理的數據的重新下載和再加工(大部分數據是歸檔),我使用digest()計算校驗和(散列)用於數據源的URL,然後用比較傳入的URL R數據文件以相應的校驗和命名。如果一個URL的校驗和與現有的R數據文件匹配,我會跳過這個URL的處理。我打算爲其他來源使用類似的方法,不是通過URL檢索數據,而是通過SQL查詢。在這種情況下,我考慮使用digest()來計算每個數據集合SQL查詢的校驗和。

但是,我的主要問題是「當我想從數據文件中將R對象加載回R時,什麼是最佳/最佳/正確的方法來區分R對象?。我考慮以下兩種方法是:

  1. 在保存數據爲R的對象的過程中,動態地創建一個查找表網址對應校驗。這將允許我從R數據文件名稱追蹤任何校驗和到​​相應的URL以及相應的數據文件(表格)。

  2. 在保存數據的過程中,請使用attr()來存儲適當的信息(完整URL或僅用於基於URL的數據收集的URL文件名,或用於基於查詢的數據收集的SQL查詢)。

我看到的,因爲它允許把URL或SQL查詢信息的即時查詢第一種方法(查找表)的利益,而第二種方法(屬性)需要通過整個列表循環爲每個數據源尋找匹配信息。同時,屬性方法在保持元數據接近數據本身方面似乎更好,而查找表方法將其移動到R代碼層,這創建了額外的依賴關係。

請告知這種情況和我的想法。

+0

我已經實現了我提到的(屬性和查找表)這兩種方法 - 只是爲了看看它是多麼容易 - 但後來意識到,我可以保持查找表中沒有R中的代碼,但作爲R對象,存儲在'.RData'文件。這將允許我將元數據存儲在數據附近,併爲不同的數據源維護不同的查找表。 –

回答

2

如果您確信您的數據源是靜態的,則可以使用以下方法。否則,問題就更加困難,每次重新下載都變得不可避免,除非源代碼爲您提供了校驗和(不需​​要提供完整的數據)。

在存儲的R對象的目錄中,比如說RDS格式,可以採用使用源的MD5哈希來命名文件的慣例。例如,如果

> digest("http://google.com/someRfile") 
[1] "bf01394aeea7b60cb0f5498c94d1b939" 

然後,你可以存儲序列化對象出現在與名bf01394aeea7b60cb0f5498c94d1b939文件中的該URL。檢查緩存命中是使用file.exists的簡單方法。如果您希望將元數據附加到對象本身,則可以將該URL作爲attr附加到對象。當然,這會造成慢速查找,因爲您必須加載每個日期文件並檢查其attr

如果你希望避免的查找表的想法(這是一個好主意!瞧到SQLite作爲一個簡單的本地存儲),你仍然可以巧妙地加以利用的文件系統。即,而不是使文件名是MD5哈希,這是一種單向散列,使用base64編碼,所以它是雙向的:

> library(RCurl) 
> base64("http://google.com") 
[1] "aHR0cDovL2dvb2dsZS5jb20=" 
> base64("aHR0cDovL2dvb2dsZS5jb20=", encode = FALSE) 
[1] "http://google.com" 

可以使用base64編碼字符串作爲您的文件名,現在可以通過簡單的base64解碼文件名來輕鬆確定序列化對象的來源。請注意,這不會使用對象的摘要,因此您仍然可以選擇將元數據附加到它。

編輯:你甚至可以結合思想的東西更聰明,消除對attr在所有的需要。也就是說,您可以使用分隔符連接R對象的MD5摘要和源URL的base64編碼,如-。然後,您可以使用list.files(dir)和正則表達式來查看具有給定源的文件是否存在。另一方面,您可以從一個R對象開始,計算其MD5摘要,並通過使用不同的正則表達式(找到MD5而不是base64編碼,例如^[^-]+而非[^-]+$)。

+0

羅伯特,謝謝你的回答!實際上,我最初的實現基於'digest'並將保存的R對象存儲在'cache'目錄中的'.RData'文件中。然後我只是使用'file.exists()'就像你在第一個建議中描述的那樣。我不知道'base64'是一個雙向哈希,這個建議非常有趣,並會考慮它,因爲它可以避免維護查找表。順便說一句,當你說這是個「好主意」時,你意味着什麼?表現還是其他標準? –

+1

只是不要嘗試'base64'編碼你的R對象! MD5大小總是32個字符,但'base64'是'O(n)',其中'n'是字符串中的字符數。 –

+1

維護表是一個不錯的主意,因爲它更易於使用。你不必像這種方法那樣知道任何約定。 –

2

你可能要檢查出UNF包GitHub上。這是Universal Numeric Fingerprint algorithm的實現,實質上是數據集的格式獨立散列(或簽名)。這爲數據提供了唯一的簽名(無論變量的命名或數據集中變量的排序如何)。任何變化都會產生不同的UNF。您可以使用它來確保兩個數據集是相同的。

你可以使用它,例如,創造你已經擁有的數據集UNFs的列表,計算出每一個新的數據集UNF和檢查,對UNF簽名的存儲列表。

全面披露:我包的作者。

另請注意:截至今天(2014/03/28),並非所有R數據類型都得到完全支持(即日期和時間被視爲字符串,而不是按照UNF算法規範正確處理),但這對您的目的可能無關緊要。

+0

托馬斯,謝謝你的回答!我一定會詳細看一下'UNF'包。從我的快速訪問到你的包的GitHub頁面,我的理解是'UNF'使用'base64'作爲底層的主要指紋算法。由於我使用的兩個主要數據源包含歸檔數據和相對較大的卷,因此我不認爲我需要本身的數據校驗和 - 對於我的目的,URL或SQL查詢的校驗和就足夠了。但是我會在將來和我的項目的不同部分研究'UNF'的可能用例。 –

+0

托馬斯,我看到你使用'Travis CI'集成來自動生成你的R包。但是,在入門指南(http://docs.travis-ci.com/user/getting-started)中我沒有看到R是有效的(官方)選項。你用這個方法(http://yihui.name/en/2013/04/travis-ci-for-r)還是那個(https://github.com/craigcitro/r-travis)?或者是其他東西?謝謝! –

+1

@AleksandrBlekh我認爲craigcitro的正在成爲共識版本。它正處於非常活躍的發展階段。 – Thomas