2015-11-14 27 views
17

我已經活躍R用戶好幾年了,而且一直困擾着我。當安裝程序包(如dplyr),必須指定包的名字作爲一個字符串即加載與安裝庫的語法。

install.packages("dplyr") 

不是

install.packages(dplyr) 

這對我來說很有意義,因爲"dplyr"將通過爲名稱該包和不作爲對象,這將暗示dplyr沒有引號。

但是,當我們去加載庫時,字符串和對象版本都會通過並加載包。以下兩個正確加載包:

library("dplyr") 
detach("package:dplyr", unload=TRUE) 
library(dplyr) 

沒有在我的工作區命名爲dplyr對象,我不明白爲什麼這兩個base功能會有不同的語法。我也不明白爲什麼沒有引號的版本不會評估對象。例如

dplyr <- "mada" 
install.packages(dplyr) 
library(dplyr) 

上面安裝mada,但負載dplyr,即使dplyr是取值爲"mada"一個對象。請注意,我正在使用Mac OS 10.10.4上的RStudio v.0.99.467,如果有問題的話。 是否有這個原因,還是僅僅是這些函數的工作方式不同?

+5

這基本上是歷史事故。 –

回答

12

library函數以包name作爲第一個參數。 name實際上是指作爲包參數傳遞的名稱,而不是與該名稱關聯的任何值。 library函數在內部將程序包參數轉換爲字符文字(character.only設置爲TRUE時除外)。

所以,

plyr <- "dplyr" 
library(plyr) 

將發生

if(!character.only) 
    package <- as.character(substitute(plyr)) 

成爲

package <- "plyr" 

install.packages需要一個特徵向量作爲待安裝的軟件包姓名(或名稱)。

dd <- "plyr" 
install.packages(dd) 

這將安裝plyr

這是因爲install.packages沒有做任何這樣的轉換pkgs的說法。所以install.packages安裝什麼pkgs是指。

4

如果要加載mada,而不是dplyr在你的例子,請嘗試使用該選項character.only = TRUE

dplyr <- "mada" 
install.packages(dplyr) 
library(dplyr, character.only=TRUE) 

參見文檔?library以獲取更多信息。

+0

+1謝謝,這非常有用。但是,我更多地要求解釋爲什麼發生這種情況,而不是解決方法。你可以評論爲什麼默認會是'character.only = F'?我會讓問題保持一段時間。 –

7

如果你通過了?library的源代碼,你會看到在line 230 click here

if (!character.only) 
      package <- as.character(substitute(package)) 

包名用戶供應將強制使用字符然後再連接到:

pkgname <- paste("package", package, sep = ":") 

這是什麼允許輸入不帶引號的庫。 install.packages不具有相同的功能。

+3

謝謝,這絕對是正確的答案。我接受了Narendra的答案,因爲它似乎是一位需要代表的新用戶,並且有正確的答案並有一個很好的解釋。我希望這對你很好,謝謝你的幫助(再次)。 –

+1

@ChrisC我不同意。你應該接受最好的答案,不要接受另一個答案,因爲你對另一個用戶感到抱歉。對於社區來說,最好的答案是被接受的。 – Jaap

+0

@Jaap感謝您的參與。在那種情況下,我認爲這兩個答案都是同樣正確的,儘管納蘭德的答案更易理解和完整,因此我會以同樣的方式接受答案。 –

7

我不明白爲什麼這兩個基本函數會有不同的語法。

很難推測特定語言設計決策的原因。允許library調用未加引號的名稱的決定受到許多知名R程序員的批評,認爲它們不合邏輯,不一致和不必要,但我們在這裏。

除此之外,它的(輕微)的說法更加方便不輸入引號,另一個潛在的原因是相似的其他語言:例如,在Python import庫通過指定像這樣的名字:import lib_nameimport 'lib_name' 。這鼓勵庫編寫者選擇語言中有效標識符的庫名稱(在Python中,加載的庫是需要引用的對象)。這在R中不太重要,除了加載它之外,很少引用該庫。

我也不明白爲什麼版本不帶引號不會評估對象。

因爲R允許non-standard evaluation。特別是,當它們被稱爲,而不是之前函數參數,只能判斷:

f = function (arg) {} 
f(stop('this won’t raise an error!')) 

arg從未使用過,所以從來不評價。

library的情況下,參數也不會被評估。相反,它通過substitute(package)以未評估的形式使用。