2012-10-14 44 views
3

在SAS中有一種創建庫的方法(使用LIBNAME)。這是很有用的,因爲當我們需要做長時間的數據處理時,我們並不總是改變數據集名稱。因此,如果我們想再次使用數據集,而不更改名稱,我們可以放入一個庫。因此,即使數據集名稱相同,但由於它們位於不同的庫中,我們可以一起處理它們。在R中創建類SAS庫L

我的問題是有R中的任何這樣的選擇,它可以創建庫(或R內單獨的文件夾),這樣我們就可以節約我們的數據呢?

這裏的例子:

假設我有一個數據集 「DAT1」。我總結了變量var1中的變量var1 & var2。

proc summary data=dat1 nway missing; 
    var var1 var2; 
    class var3; 
    output out=tmp.dat1 (drop = _freq_ _type_) sum = ; 
    run; 

然後我合併DAT1與DAT2,這是另一個dataset.Both DAT1 & DAT2具有共同變量VAR3,與我合併。我再次創建了新的數據集dat1。

proc sql; 
    create table dat1 as 
    select a.*,b.* 
    from dat1 a left join tmp.dat2 b 
    on a.var3=b.var3; 
    quit; 

現在,我又總結數據集DAT1合併,以檢查是否VAR1 &變種2的值&之前保持不變,合併後之後。

proc summary data=dat1 nway missing; 
    var var1 var2; 
    class var3; 
    output out=tmp1.dat1 (drop = _freq_ _type_) sum = ; 
    run; 

R中的等效代碼將是

dat3<-ddply(dat1,.(var3),summarise,var1=sum(var1,na.rm=TRUE),var2=sum(var2,na.rm=TRUE)) 

dat1<-sqldf("select a.*,b.* from dat1 a left join dat2 b on a.var3=b.var3") 

dat4<-ddply(dat1,.(var3),summarise,var1=sum(var1,na.rm=TRUE),var2=sum(var2,na.rm=TRUE)) 

在SAS的情況下,我使用的只是2數據集名稱。但是在R的情況下,我使用4個數據集名稱。因此,如果我正在編寫4000行代碼進行數據處理,那麼有時數據集名稱過多有時會變得難以逾越。在sas中,與使用默認工作庫以外的2個庫tmp,tmp1相同的數據集名稱變得很容易。

在SAS,庫被定義爲:

LIBNAME tmp "directory_path\folder_name"; 

在該文件夾中,DAT1將被存儲。

+4

這個問題可能對SAS用戶有意義,但對我們其他人來說沒有意義。你爲什麼不解釋你想從R中得到什麼,以及你目前的做事方式缺乏?也許用[可重現的例子](http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example)? –

+1

要保存數據集,請參閱'?save'('?load'來加載它們)。 – sgibb

+0

您的問題是您正在編寫4000行腳本。在SAS中,這可能不是一個問題,超過五行的任何內容都已經混淆了,但是在R中,你不應該寫任何超過十行的東西,而不會想到「嘿,這應該被包含在一個函數中。 – Spacedman

回答

3

下面是使用SOAR包,並命名爲環境

從暗角

對象,不需要在內存中始終保持引用的例子。功能保存可用於將文件中的對象保存在文件中,通常爲.RData擴展名。然後可以將這些對象從內存中移除,並在稍後使用加載函數進行顯式調用。

的SOAR包提供簡單的方法來存儲在盤上的對象,但以這樣的方式使得它們保持爲承諾的搜索路徑上可見的,即,如果並且當再次需要的對象被自動加載到存儲器。它使用相同的延遲加載機制,包,但這裏提供的功能更加動態和靈活的

這將是有益的閱讀whole vignette

library(SOAR) 
library(plyr) 
library(sqldf) 
set.seed(1) 
# create some dummy data create a named envirment 
tmp <- new.env(parent = .GlobalEnv) 
dat1 <- data.frame(var1 = rnorm(50), var2 = sample(50, replace = TRUE), var3 = sample(letters[1:5], 
    50, replace = TRUE)) 
tmp$dat1 <- ddply(dat1, .(var3), summarise, var1 = sum(var1, na.rm = TRUE), 
    var2 = sum(var2, na.rm = TRUE)) 
tmp$dat2 <- data.frame(Var3 = sample(letters[1:5], 20, replace = TRUE), Var4 = 1:20) 
# store as a SOAR cached object (on disc) 
Store(tmp, lib = "tmp") 

# replace dat1 within the global enviroment using sqldf create a new 
# environment to work in with the correct version of dat1 and dat2 
sqlenv <- tmp 
sqlenv$dat1 <- dat1 

dat1 <- sqldf("select a.*,b.* from dat1 a left join dat2 b on a.var3=b.var3", 
    envir = sqlenv) 

# create a new named enviroment tmp1 
tmp1 <- new.env(parent = .GlobalEnv) 

tmp1$dat1 <- ddply(dat1, .(var3), summarise, var1 = sum(var1, na.rm = TRUE), 
    var2 = sum(var2, na.rm = TRUE)) 

# store using a SOAR cache 
Store(tmp1, lib = "tmp") 


tmp1$dat1 

## var3 var1 var2 
## 1 a 1.336 378 
## 2 b 8.514 1974 
## 3 c 5.795 624 
## 4 d -8.828 936 
## 5 e 20.846 1490 

tmp$dat1 

## var3 var1 var2 
## 1 a 0.4454 126 
## 2 b 1.4190 329 
## 3 c 1.9316 208 
## 4 d -2.9427 312 
## 5 e 4.1691 298 

我不知道,你應該期望tmp1$dat1tmp$dat1是相同的(給我的例子反正)

+1

這真的有幫助。 SAS中的庫選項是我無法在R中複製到目前爲止的一個方面。但你的回答也消除了這個障礙。非常感謝! – Beta

6

從我可以從SAS onlinehelp聚集,一個SAS庫是一組保存在文件夾中的數據集,並可以作爲一個單元進行引用。在R中相當於將保存您想使用save保存將R對象:

save(obj1, obj2, etc, file = "stored_objects.rda") 

加載可使用load來完成的對象。

編輯:我真的不明白爲什麼有一個額外的對象,或者兩個這麼多的問題。但是,如果您想減少對象的數量,只需將結果放入list即可。

+0

感謝您的回答保羅。但遺憾的是,這不是我要找的。在我的情況下,obj1&obj2具有相同的名稱。但是保存的文件夾不同。所以即使我有相同的數據集名稱,我可以將它用作不同的數據集,因爲有「庫」選項。 – Beta

+0

從SAS程序員的角度來看,Paul的答案似乎是正確的。儘管SAS可以同時訪問跨不同庫的對象,而R只能在當前工作區中工作,但您應該能夠在需要時通過從不同工作區保存和加載適當對象來完成您需要執行的操作。注意:這僅適用於加載/保存對象,而不是圖像,這當然會消除當前的工作空間。 –

+0

@RalphWinters的SAS庫是否也提供自動內存溢出計算(如果數據大小超過RAM)? –

2

命名環境是許多實現這聽起來像你希望的方式之一。

就個人而言,如果沒有大量的不同的數據幀或列表,我向組織它的其他方式,如無論是數據幀或列表裏面傾斜,這取決於你的數據是如何構成的。但是,如果每件事物都由許多不同類型的數據和功能組成,環境可能會更好。它們在help中描述,並且一些posts to r-blogs討論它們。

但細想起來,R-Studio的projects可能會更接近您要思考的問題(如果你不使用的R-Studio已經,我強烈推薦)的方式。看看項目是如何工作的。

+0

非常感謝。對不起,延遲的回覆佔用了。我實際上在使用R-Studio。但由於某種原因,從未探索過項目選項。但我會這樣做。除了mnel的回答之外,它可能會給我額外的好處。很高興看到你對命名環境的觀點終於給了我一個答案。 :) – Beta

5

有SAS的圖書館的兩個獨立的方面(似乎),你有感興趣的

在該數據文件存儲
  • 能夠容易地通過僅僅指定不同位置
  • 的順序考慮到這些分析指向一個不同的組具有相同名稱的數據集的目錄的

    • 規格。

      回答第一個問題是R和SAS有關於數據存儲方式的不同模型。 R將數據存儲在內存中,按照特定搜索順序排列的環境中組織。 SAS將數據存儲在磁盤上,並且數據集的名稱與指定目錄內的文件名相對應(有可能將內存緩存用於優化,但概念上這是數據存儲的方式)。 R可以使用save()將(一組)對象存儲在磁盤上的文件中,並使用load()將它們帶回到內存中。文件名和目錄可以在這些函數調用中指定(因此Paul's answer)。您可能有多個.RData文件,每個文件都包含名爲dat1,dat2等的對象,這些對象可以在運行分析之前加載,並且可以將結果寫入(其他).RData文件。

      另一種方法是使用其中一種擴展名,它給出的數據類型由磁盤存儲而不是內存支持。我還沒有與他們任何人討論他們在這種情況下工作的情況,但這是一種選擇。 [編輯:mnel's answer有一個這個想法的詳細例子。]

      你的第二部分可以通過不同的方式。由於R使用內存數據,答案將圍繞安排不同環境(每個環境可能包含不同但命名相同的數據集)以及控制通過搜索路徑中的環境訪問哪一個環境(哪些環境從搜索路徑訪問)來實現(哪些環境可以使用Glen_b's answer朝着)。您仍然沒有數據的磁盤支持,但這是以前的問題。

      最後,@ joran的警告是相關的。在R中潛在不同(但相關)的數據集上執行一組任務的問題的解決方案是編寫一個函數來完成這項工作。該函數具有參數。在該函數中,參數由參數列表中給出的名稱引用。當函數被調用時,函數調用指定哪一組數據被髮送給它;函數內部和外部的名字不需要彼此有任何關係。關於將多組數據存儲在列表中的建議以這種方式隱含地接近問題;該函數將依次調用列表中的每組數據。那麼名稱並不重要。

    +0

    謝謝Brians!更重要的是將所有答案彙總在一起。 – Beta