代码之家  ›  专栏  ›  技术社区  ›  stackinator Brenton Wiernik

关于tidyeval,`sym()`做了什么?

  •  2
  • stackinator Brenton Wiernik  · 技术社区  · 5 年前
    library(tidyverse)
    input_name <- "birth_year"
    input_value <- 19
    
    quo(filter(starwars, !!input_name == !!input_value))       # line 5
    quo(filter(starwars, !!sym(input_name) == !!input_value))  # line 6
    

    第5行和第6行的区别是什么,以及 sym() 功能?为什么是 叙() 仅在第6行方程式左侧需要?

    是点 叙() 把字符串取下来,然后把它们放进符号中?

    第5行

    <quosure>
      expr: ^filter(data, "birth_year" == 19)
      env:  global
    

    第6行

    <quosure>
      expr: ^filter(data, birth_year == 19)
      env:  global
    
    2 回复  |  直到 5 年前
        1
  •  2
  •   akrun    5 年前

    在第一种情况下,不计算列,而是计算字符串。但是,通过转换到 symbol 然后计算它,它返回列值。这个 sym 在中是必需的 lhs 因为我们不是要获取文本值,而是要提取列值

    根据 ?sym

    sym()从字符串创建符号,syms()从字符向量创建符号列表。

    以及 ?"!!"

    这个!!运算符取消对其参数的引号。它会在周围环境中立即得到评估。

        2
  •  2
  •   Artem Sokolov    5 年前

    答案是肯定的,目标是 sym() 就是把字符串解析成符号。你需要这个的原因在平等的左边可以看到 ?filter 以下内容:

     ...: Logical predicates defined in terms of the variables in
          ‘.data’. Multiple conditions are combined with ‘&’. Only rows
          where the condition evaluates to ‘TRUE’ are kept.
    

    filter( starwars, "birth_year" == 19 ) 将始终不返回任何结果,因为 string literal "birth_year" 从不等于整型文字 19 (它被隐式地强制为字符文本 "19" 相比之下)。通过使用 sym ,您正在有效地将该字符串解析为符号,强制 filter 查看名为 birth_year 在数据帧中 starwars ,而不是文字字符串 “生日年” .

    相反,你 不要 需要 叙() 在方程的右边,因为没有列 十九 在里面 星际大战 你对实际的文字价值感兴趣 十九 相反。如果要比较数据框中的两列,则需要 叙() 在平等的两边。例如,

    name1 <- "skin_color"
    name2 <- "eye_color"
    filter( starwars, !!sym(name1) == !!sym(name2) )
    # # A tibble: 6 x 13
    #   name  height  mass hair_color skin_color eye_color birth_year gender homeworld
    #   <chr>  <int> <dbl> <chr>      <chr>      <chr>          <dbl> <chr>  <chr>    
    # 1 Wick…     88    20 brown      brown      brown              8 male   Endor    
    # 2 Jar …    196    66 none       orange     orange            52 male   Naboo    
    # 3 Eeth…    171    NA black      brown      brown             NA male   Iridonia 
    # 4 Mas …    196    NA none       blue       blue              NA male   Champala 
    # ...