library(rlang)
您刚刚附加了rlang
,您的搜索路径现在如下所示:
search()
# [1] ".GlobalEnv" "package:rlang" "package:stats"
# [4] "package:graphics" "package:grDevices" "package:utils"
# [7] "package:datasets" "package:methods" "Autoloads"
# [10] "package:base"
如果您在命令行以交互方式执行此操作,则应该发生在.GlobalEnv
:
quo <- quo(letters)
ls(.GlobalEnv)
# [1] "quo"
现在quo
或get("quo")
开始搜索quo
in .GlobalEnv
,在那里找到它(您刚刚创建的 quosure)并停止:
quo
get("quo")
get("quo", .GlobalEnv)
# <quosure: global>
# ~letters
如果要查找该函数,则必须绕过.GlobalEnv
并在其封闭环境中开始搜索,package:rlang
. 你很幸运,这就是它所在的地方:
get("quo", as.environment("package:rlang"))
# function (expr)
# {
# enquo(expr)
# }
# <environment: namespace:rlang>
(哦,namespace:rlang
你看到的不是我们找到的地方quo
,而是它的封闭环境,即当它被调用时它将开始自己的搜索。参见世界地图:来源:Suraj Gupta http://blog。 obeautifulcode.com/R/How-R-Searches-And-Finds-Stuff/)
> sapply(search(), function(x) "quo" %in% ls(x))
.GlobalEnv package:rlang package:stats package:graphics
TRUE TRUE FALSE FALSE
package:grDevices package:utils package:datasets package:methods
FALSE FALSE FALSE FALSE
Autoloads package:base
FALSE FALSE
如果你已经知道你正在寻找一个函数,你可以使用这个方便fget
的pryr
方法来忽略所有不是函数的东西:
pryr::fget("quo")
# function (expr)
# {
# enquo(expr)
# }
# <environment: namespace:rlang>
(注意:match.fun
在编写自己的函数时也可以派上用场)。
或者你可以让R变得聪明,直接使用parens,R会知道它必须寻找一个函数,这是在做的:
quo <- quo(toupper(!! quo))
(同时比较:
> bar
Error: object 'bar' not found
> bar()
Error in bar() : could not find function "bar"
错误消息提示 R 找不到/寻找什么,有和没有括号。)
现在为了好玩,让我们附上整个 tidyverse:
library(tidyverse)
搜索路径变得更加混乱:
search()
# [1] ".GlobalEnv" "package:forcats" "package:stringr"
# [4] "package:dplyr" "package:purrr" "package:readr"
# [7] "package:tidyr" "package:tibble" "package:ggplot2"
# [10] "package:tidyverse" "package:rlang" "package:stats"
# [13] "package:graphics" "package:grDevices" "package:utils"
# [16] "package:datasets" "package:methods" "Autoloads"
# [19] "package:base"
如果我们很好奇并想知道在哪里quo
找到,我们可以使用where
from pryr
。同样,我们应该绕过.GlobalEnv
并在其封闭环境中启动,package:forcats
例如:
pryr::where("quo", env = "package:forcats")
# Using environment package:forcats
# <environment: package:dplyr>
# attr(,"name")
# [1] "package:dplyr"
# attr(,"path")
# [1] "/home/aurele/R/x86_64-pc-linux-gnu-library/3.4/dplyr"
惊喜,quo
现在发现在package:dplyr
而不是package:rlang
. 这是因为package:dplyr
在搜索路径中出现之前,并且当它发生时,它会重新导出quo
以rlang
使其直接在dplyr
.
> sapply(search(), function(x) "quo" %in% ls(x))
.GlobalEnv package:forcats package:stringr package:dplyr
TRUE FALSE FALSE TRUE
package:purrr package:readr package:tidyr package:tibble
FALSE FALSE FALSE FALSE
package:ggplot2 package:tidyverse package:rlang package:stats
FALSE FALSE TRUE FALSE
package:graphics package:grDevices package:utils package:datasets
FALSE FALSE FALSE FALSE
package:methods Autoloads package:base
FALSE FALSE FALSE