【问题标题】:R: Understanding standard evaluation in mutate_R:了解 mutate_ 中的标准评估
【发布时间】:2016-05-16 17:18:04
【问题描述】:

我正在尝试混合常量和带引号的变量名,正如Non-standard evaluation vignette 中所建议的那样,使用lazyeval::interp

这是一个做我想做的例子:

# 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)

请注意,我已将惰性求值的结果分配给字符向量 ("(Weird) Variable name")。但是,当我将惰性求值的结果分配给var_name 时,它会分配给一个名为"var_name" 的文字。有人可以帮助理解这种行为吗?

# 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)

这两个函数不应该有相同的结果吗?

【问题讨论】:

    标签: r dplyr lazy-evaluation


    【解决方案1】:

    当直接调用任何 R 函数时,不能使用变量作为参数名称(参数名称是指函数调用中 = 符号左侧的那些东西)。参数名称始终被视为文字值。这两个是一样的

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

    或者看看

    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 不必是第一个工作的变量,即使这样的变量存在,它也会被忽略。解析时引号基本上被丢弃了——它不是一个真正的字符值,它是一个符号。

    如果您需要动态设置变量名称,则需要将参数构建为列表并设置该列表的名称。

    如果您要将参数名称作为字符值传递,您可以使用setNames 设置该参数名称,然后您可以将其传递给mutate_ 函数的.dots= 参数。例如

    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)
    

    这是因为这些都是等价的

    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"))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-03-23
      • 2015-03-10
      • 1970-01-01
      • 2016-09-18
      • 1970-01-01
      • 2019-09-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多