2016-05-16 4 views
12

Ich versuche, Konstanten und zitierte Variablennamen zu mischen, wie in der Non-standard evaluation vignette unter Verwendung lazyeval::interp vorgeschlagen. HierR: Grundlegendes zur Standardauswertung in mutate_

ist ein Beispiel, das tut, was ich will:

# create sample dataset 
df_foo = data_frame(
    `(Weird) Variable name` = 100, 
    group_var = sample(c("Yes", "No"), size = 100, replace = TRUE) 
) 

# function to update the value of weirdly named variable 
update_var_1 = function(var_name) { 
    df_foo %>% 
    mutate_(
     "(Weird) Variable name" = 
     interp(quote(ifelse(group_var_val == "Yes", var_name_val/10, var_name_val/20)), 
       group_var_val = as.name("group_var"), 
       var_name_val = as.name(var_name)) 
    ) 
} 

# test the function 
update_var_1("(Weird) Variable name") %>% 
    head(n = 20) 

Bitte beachten, dass ich das Ergebnis der lazy evaluation den Zeichenvektor zugeordnet habe ("(Weird) Variable name"). Allerdings, wenn ich das Ergebnis der Lazy-Auswertung var_name zuweisen, die einem Literal namens "var_name" zugewiesen wird. Kann jemand helfen, dieses Verhalten zu verstehen?

# function to update the value of weirdly named variable 
update_var_2 = function(var_name) { 
    df_foo %>% 
    mutate_(
     var_name = 
     interp(quote(ifelse(group_var_val == "Yes", var_name_val/10, var_name_val/20)), 
       group_var_val = as.name("group_var"), 
       var_name_val = as.name(var_name)) 
    ) 
} 

# test the function 
update_var_2("(Weird) Variable name") %>% 
    head(n = 20) 

Sollten die beiden Funktionen nicht identische Ergebnisse haben?

Antwort

18

Wenn Sie eine R-Funktion direkt aufrufen, können Sie keine Variablen für Parameternamen verwenden (und mit Parameternamen meine ich die Dinge, die sich in einem Funktionsaufruf links vom Symbol = befinden). Parameternamen werden immer als Literalwerte verwendet. Diese beiden sind die gleichen

f(a=3) 
f("a"=3) 

oder schauen Sie auf

deparse(quote(f(a=3))) 
# [1] "f(a = 3)" 
deparse(quote(f("a"=3))) 
# [1] "f(a = 3)" 
a <- "b" 
deparse(quote(f(a=3))) 
# [1] "f(a = 3)" 

a hat keine Variable für die ersten sein, zu arbeiten, und selbst wenn eine solche Variable existiert, wird er ignoriert. Die Zitate werden beim Parsen grundsätzlich rausgeworfen - es ist nicht wirklich ein Zeichenwert, es ist ein Symbol.

Wenn Sie Variablennamen dynamisch festlegen müssen, müssen Sie Ihre Parameter als Liste erstellen und die Namen dieser Liste festlegen.

Wenn Sie vorhaben, den Namen des Parameters als Zeichenwert zu übergeben Sie setNames verwenden können, die Parameternamen festlegen, die Sie dann auf den .dots= Parameter der mutate_ Funktion übergeben können. Zum Beispiel

update_var_3 <- function(var_name) { 
    df_foo %>% 
    mutate_(.dots= 
    setNames(list(
     interp(quote(ifelse(group_var_val == "Yes", var_name_val/10, var_name_val/20)), 
       group_var_val = as.name("group_var"), 
       var_name_val = as.name(var_name) 
    )), var_name)) 
} 

update_var_3("(Weird) Variable name") %>% 
    head(n = 20) 

Dies liegt daran, diese alle sind gleichwertig

df <- data_frame(a=1:10) 
mutate(df, a=a+5) 
mutate(df, "a"=a+5) #identical to first, not really a character variable 
mutate_(df, a=quote(a+5)) 
mutate_(df, .dots=list(a=quote(a+5))) 
mutate_(df, .dots=setNames(list(quote(a+5)),"a"))