关于 tidyeval,`sym()` 做了什么?
What does `sym()` do regarding tidyeval?
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()
函数的使用?为什么 sym()
只需要在第 6 行的等式左侧?
sym()
的目的是获取字符串并将其取消引用为符号吗?
第 5 行
<quosure>
expr: ^filter(data, "birth_year" == 19)
env: global
第 6 行
<quosure>
expr: ^filter(data, birth_year == 19)
env: global
在第一种情况下,不会评估列,评估的是字符串。但是,通过转换为 symbol
并计算它,它 returns 列值。 lhs
中需要 sym
因为我们不是要获取字面值,而是要提取列值
根据?sym
sym() creates a symbol from a string and syms() creates a list of symbols from a character vector.
和?"!!"
The !! operator unquotes its argument. It gets evaluated immediately in the surrounding context.
答案是肯定的,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 )
将始终 return 没有结果,因为 string literal "birth_year"
永远不会等于整数文字 19
(它被隐式强制为比较中的字符文字 "19"
)。通过使用 sym
,您可以有效地将字符串解析为一个符号,从而强制 filter
查看数据框 starwars
中名为 birth_year
的列,而不是文字字符串 "birth_year"
.
相反,你不需要等式右边的sym()
,因为[=]中没有第19
列21=],而您对实际文字值 19
感兴趣。如果您要比较数据框中的两列,那么您需要在等式的两边使用 sym()
。例如,
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
# ...
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()
函数的使用?为什么 sym()
只需要在第 6 行的等式左侧?
sym()
的目的是获取字符串并将其取消引用为符号吗?
第 5 行
<quosure>
expr: ^filter(data, "birth_year" == 19)
env: global
第 6 行
<quosure>
expr: ^filter(data, birth_year == 19)
env: global
在第一种情况下,不会评估列,评估的是字符串。但是,通过转换为 symbol
并计算它,它 returns 列值。 lhs
中需要 sym
因为我们不是要获取字面值,而是要提取列值
根据?sym
sym() creates a symbol from a string and syms() creates a list of symbols from a character vector.
和?"!!"
The !! operator unquotes its argument. It gets evaluated immediately in the surrounding context.
答案是肯定的,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 )
将始终 return 没有结果,因为 string literal "birth_year"
永远不会等于整数文字 19
(它被隐式强制为比较中的字符文字 "19"
)。通过使用 sym
,您可以有效地将字符串解析为一个符号,从而强制 filter
查看数据框 starwars
中名为 birth_year
的列,而不是文字字符串 "birth_year"
.
相反,你不需要等式右边的sym()
,因为[=]中没有第19
列21=],而您对实际文字值 19
感兴趣。如果您要比较数据框中的两列,那么您需要在等式的两边使用 sym()
。例如,
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
# ...