R軟體中的attach 與時下的 with 指令

最近在學會(http://www.r-software.org/)的台灣 R 軟體使用者論壇上有人提起 attach 指令,讓我想起前一陣子看到的 with 指令。過去我們常用 attach 指令,將資料框物件附加到搜尋路徑(search path)上,使得資料框中的變數對於 R 的直譯器(interpreter)而言是可見的(visible),省去須敲擊資料框全名方能引用變數的麻煩!以 car 套件中的資料框 Duncan 為例,

> library(car)

> head(Duncan)

                  type   income   education  prestige

accountant  prof          62              86          82

pilot            prof          72              76          83

architect      prof          75              92         90

author          prof          55             90         76

chemist       prof          64              86         90

minister       prof          21              84         87

> summary(Duncan)

    type               income        education               prestige  

bc  :21     Min.     :  7.00    Min.     :  7.00    Min.     : 3.00 

prof:18    1st Qu. : 21.00   1st Qu. : 26.00   1st Qu. :16.00

wc  : 6     Median :42.00   Median  :45.00   Median :41.00

               Mean    :41.87   Mean    :52.56    Mean    :47.69

               3rd Qu. :64.00   3rd Qu.: 84.00    3rd Qu. :81.00

               Max.     :81.00   Max.   :100.00    Max.    :97.00 

資料框名後接串列取值字元($)加變數名結果如下:

> Duncan$prestige

[1]   82 83 90 76 90 87 93 90 52 88 57 89 97 59 73 38 76 81 45 92 39 34 41 16 33
[26] 53 67 57 26 29 10 15 19 10 13 24 20 7 3 16 6 11 8 41 10> mean(Duncan$prestige)

[1] 47.68889

attach 資料框後,在 detach 之前都可直接取用資料框中所有變數。

> attach(Duncan)

> prestige

[1]   82 83 90 76 90 87 93 90 52 88 57 89 97 59 73 38 76 81 45 92 39 34 41 16 33
[26] 53 67 57 26 29 10 15 19 10 13 24 20 7 3 16 6 11 8 41 10

> detach(Duncan)

以下是一些不贊成 attach 的理由:首先是附加上之資料框變數會遮罩住其它同名的變數;再者,attach 是將資料框一時的快照(snapshot)複本,附加在全域環境(global environment)之後,萬一資料框有所變動,是不會反映在其複本上;最後,使用者經常會忘記 detach 暫時不用的資料框,徒增資料分析過程的混亂。因此,避免附加資料框到搜尋路徑的做法除了前述的全名引用外,也可以用 with 指令,使得 R 在該資料框環境下評析後續的指令。

> with(Duncan, mean(prestige))
[1] 47.68889

> with(Duncan, lm(prestige ~ income + education))

Call:
lm(formula = prestige ~ income + education)

Coefficients:
(Intercept)   income   education
   -6.0647    0.5987       0.5458

當然,我們也可以利用 R 中許多統計建模函數的 data 參數,其結果與前面的 with 指令相同。

(lm(prestige ~ income + education, data = Duncan))

Call:
lm(formula = prestige ~ income + education)

Coefficients:
(Intercept)   income   education 
   -6.0647    0.5987       0.5458

最後,取出部分子集與資料繪圖等工作也可搭配 with 指令來使用,此處互動式繪圖的結果並未顯示於圖面上。

> with(Duncan, Duncan[type == "bc" & income > mean(income), ])

                              type  income  education  prestige

electrician                  bc         47            39           53

RR.engineer               bc         81            28           67

plumber                     bc        44            25           29

streetcar.motorman     bc        42            26           19

> with(Duncan,{

+ plot(education, prestige)

+ identify(education, prestige, row.names(Duncan))

+ })

f:id:DataScience:20140824174643p:plain

參考資料:Fox, J. and Weisberg, S. (2011), An R Companion to Applied Regression, 2nd Edition,Sage.

 

撰文者:
鄒慶士 博士
現任:
北商資訊與決策科學所教授
中華 R 軟體學會理事長
信箱:
vince.tsou@gmail.com