2009-08-21 67 views
26

許多介紹R書籍和指南的開頭都是附加data.frame的做法,以便您可以通過名稱調用變量。我總是發現用$表示法或方括號切片[,2]來調用變量是有利的。這樣我就可以使用多個data.frame而不會混淆它們和/或使用迭代來連續調用感興趣的列。我注意到谷歌最近發佈coding guidelines for R其中包括線您是否使用attach()或通過名稱或切片調用變量?

1)附:避免使用它

人們如何看待這種做法?

回答

25

我從不使用attach。 withwithin是你的朋友。

示例代碼:

> N <- 3 
> df <- data.frame(x1=rnorm(N),x2=runif(N)) 
> df$y <- with(df,{ 
    x1+x2 
}) 
> df 
      x1   x2   y 
1 -0.8943125 0.24298534 -0.6513271 
2 -0.9384312 0.01460008 -0.9238312 
3 -0.7159518 0.34618060 -0.3697712 
> 
> df <- within(df,{ 
    x1.sq <- x1^2 
    x2.sq <- x2^2 
    y <- x1.sq+x2.sq 
    x1 <- x2 <- NULL 
}) 
> df 
      y  x2.sq  x1.sq 
1 0.8588367 0.0590418774 0.7997948 
2 0.8808663 0.0002131623 0.8806532 
3 0.6324280 0.1198410071 0.5125870 

編輯:哈德利提到評價變換。這裏是一些代碼:

> transform(df, xtot=x1.sq+x2.sq, y=NULL) 
     x2.sq  x1.sq  xtot 
1 0.41557079 0.021393571 0.43696436 
2 0.57716487 0.266325959 0.84349083 
3 0.04935442 0.004226069 0.05358049 
+3

'transform'是內部另一個有用的變體。 – hadley 2009-08-23 14:24:37

+1

其實我只注意到不像'attach()','with()'不能「通過」解析函數。首先設置'printx < - function {print(x)}'。現在,即使'with(list(x = 42),print(x))'和'attach(list(x = 42)),'with(list(x = 42),printx())'失敗。 printx()'成功了! :( – 2011-09-20 12:52:06

3

我更喜歡不使用attach(),因爲每次調用attach()時都會多次運行一批代碼,這太容易了。數據幀每次都添加到搜索路徑中,不必要地擴展它。當然,良好的編程習慣也是在代碼塊的末尾加上detach(),但這經常被遺忘。

取而代之,我使用xxx $ y或xxx [,「y」]。它更透明。

另一種可能性是使用許多函數中可用的數據參數,這些函數允許在數據框中引用各個變量。例如,lm(z ~ y, data=xxx)

+0

有時我從各種數據框和全局變量中調用,而這個系統意味着從來沒有執行過錯誤的計算。 – Michelle 2012-01-26 16:00:06

8

附件的主要問題是它可能會導致不需要的行爲。假設你的工作空間中有一個名爲xyz的對象。現在你附加一個名爲xyz的列的數據框abc。如果你的代碼引用xyz,你能保證這是對象或數據幀列的引用嗎?如果你不使用attach,那麼很容易。只是xyz指的是對象。 abc $ xyz指向數據框的列。

在教科書中經常使用attach的主要原因之一是它縮短了代碼。

+0

我注意到一些教科書上說:「不要這樣做,附加被用來簡化例子」。 – Michelle 2012-01-26 16:01:29

13

我更喜歡使用with以獲得上的單個命令的attach等效:

with(someDataFrame, someFunction(...)) 

這也自然會導致一個形式,其中subset是第一個參數:

with(subset(someDataFrame, someVar > someValue), 
     someFunction(...)) 

其我們很清楚地知道,我們在選擇數據時進行操作。雖然許多建模函數都有datasubset的論點,但上面的使用更加一致,因爲它也適用於那些沒有datasubset參數的函數。

7

「附加」是一種邪惡的誘惑。只有在教室設置的地方纔有效,其中一個被給予單個數據幀,並且預計寫入代碼行以對該一個數據幀進行分析。一旦分配完成並交付,用戶不太可能再次使用該數據。

然而,在現實世界中的,更多的數據幀可以被添加到特定項目中的數據集合中。此外,人們經常複製和粘貼代碼塊以用於類似的事情。通常是從幾個月前做的事情中借用,而不記得從哪裏調用的細微差別。在這種情況下,人們會因先前使用「附加」而淹死。

2

雖然我也不喜歡使用attach(),但是當您有幾個使用它的函數時,如果需要在程序的整個生命週期中持久保存一個對象(在本例中爲data.frame),它確實佔有一席之地。與其將對象傳遞給每個使用它的R函數,我認爲將它保留在一個地方並根據需要調用它的元素會更方便。

這就是說,如果我知道我有多少內存可用,並且只有在確定我detach()這個data.frame一旦超出範圍時,我纔會使用它。

我有道理嗎?

3

就像Leoni說的,withwithinattach的完美替代品,但我不會完全否定它。我有時會使用它,當我直接在R提示符下工作,並想在將腳本寫入腳本之前先測試一些命令。特別是在測試多個命令時,attach對於withwithin可能是一個更有趣,更方便,甚至無害的替代方案,因爲在運行attach之後,命令提示符已清除,可供您編寫輸入並查看輸出。

完成後請確保您的數據爲detach

相關問題