2015-07-13 51 views
2

編寫函數時,檢查參數的類型非常重要。例如,取該正在執行子集以下(不一定是有用的)功能:檢查函數的表達式參數

data_subset = function(data, date_col) { 

     if (!TRUE %in% (is.character(date_col) | is.expression(date_col))){ 
     stop("Input variable date is of wrong format") 
     } 

     if (is.character(date_col)) { 
     x <- match(date_col, names(data)) 
     } else x <- match(deparse(substitute(date_col)), names(data)) 

     sub <- data[,x] 
} 

我想允許用戶提供應(提取爲字符或表達式列例如所謂的「日期列「與剛纔的日期)。在開始時,我想檢查date_col的輸入實際上是一個字符值還是一個表達式。然而,「is.expression」不工作:

Error in match(x, table, nomatch = 0L) : object '...' not found 

由於deparse(替代))的作品,如果一個提供我想表達「is.expression」必須正常工作。 這裏有什麼不對,誰能給我一個提示?

回答

1

我認爲你不是在尋找is.expression,而是爲is.name

棘手的部分是得到date_col類型,並檢查它是否是類型的角色,只有當它是name。如果您在名稱中調用is.character,那麼它將得到評估,通常會導致錯誤,因爲該對象未定義。

要做到這一點,short circuit evaluation可用於:在

if(!(is.name(substitute(date_col)) || is.character(date_col))) 

is.character只調用如果is.name回報FALSE

你的功能可以歸結爲:

data_subset = function(data, date_col) { 

    if(!(is.name(substitute(date_col)) || is.character(date_col))) { 
    stop("Input variable date is of wrong format") 
    } 

    date_col2 <- as.character(substitute(date_col)) 
    return(data[, date_col2]) 
} 

當然,你可以使用if(is.name(…))只能轉換爲字符時date_col是出了名。

這工作:

testDF <- data.frame(col1 = rnorm(10), col2 = rnorm(10, mean = 10), col3 = rnorm(10, mean = 50), rnorm(10, mean = 100)) 

data_subset(testDF, "col1") # ok 
data_subset(testDF, col1) # ok 
data_subset(testDF, 1) # Error in data_subset(testDF, 1) : Input variable date is of wrong format 

不過,我不認爲你應該這樣做。請看下面的例子:

var <- "col1" 
data_subset(testDF, var) # Error in `[.data.frame`(data, , date_col2) : undefined columns selected 

col1 <- "col2" 
data_subset(testDF, col1) # Gives content of column 1, not column 2. 

雖然這個「工作原理設計的」,這是混淆了,因爲除非仔細閱讀你的函數的文檔,人們會期望得到在第一種情況col1col2在第二種情況下。

濫用一個famous quote

一些人,當遇到一個問題,認爲「我知道,我將使用非標準的評價。」現在他們有兩個問題。

哈德利韋翰在Non-standard evaluation

非標準評價,您可以編寫非常強大的功能。但是,他們很難理解和編程。除了始終提供逃生艙外,在將其用於新領域之前,請仔細考慮NSE的成本和收益。

除非您希望允許跳過列名稱周圍的引號,否則不要這麼做。

+0

非常感謝您的詳細解答!迄今爲止還沒有聽說過短路評估。 ;) 我將放棄輸入表達式作爲參數的可能性。保存兩個按鍵不值得可能發生的複雜情況,你是對的。 – RomanB