;tidyselect";包提供了一个选择助手函数CCD_ 1。where
用于选择具有自定义功能的数据帧列。它是来自";tidyselect";。这意味着where
不会加载到您的命名空间中,您只能通过tidyselect:::where
调用它。
然而,我从dplyr的小插曲中看到了以下示例:列操作。
starwars %>%
summarise(across(where(is.character), ~ length(unique(.x))))
#> # A tibble: 1 x 8
#> name hair_color skin_color eye_color sex gender homeworld species
#> <int> <int> <int> <int> <int> <int> <int> <int>
#> 1 87 13 31 15 5 3 49 38
在这个例子中,where
是在没有前缀"0"的情况下编写的;tidyselect:::"但很明显,代码中并没有错误,它产生了有意义的结果。这对我来说似乎很奇怪。我想知道为什么代码运行正常。
我想这是由于";代码引用";,这是tidyval方法论的一部分。粗略地说,代码引用将代码挂起作为表达式,并稍后在"中对表达式求值;内部环境";。这只是一个直观的猜测,我不知道如何测试它
我希望有人能帮助我;其中";问题,或者给我留下一些关于代码如何工作的参考。
您没有说明示例中附加了哪些包,但假设唯一附加的包是dplyr
。
library(dplyr)
首先,我们注意到函数where
没有被附加,即当前R会话不知道。我们只需在控制台中键入其名称(不带括号(即可进行检查。如果附加了函数,我们现在可以看到它的源代码。相反,我们得到一个错误,即找不到对象where
。
然而,我们注意到dplyr
附加了where
0的其他函数,starts_with
就是一个例子。如果我们重复在控制台中键入名称的实验,我们现在可以看到源代码,以及函数源自tidyselect
命名空间:
> starts_with
function (match, ignore.case = TRUE, vars = NULL)
{
check_match(match)
vars <- vars %||% peek_vars(fn = "starts_with")
if (ignore.case) {
vars <- tolower(vars)
match <- tolower(match)
}
flat_map_int(match, starts_with_impl, vars)
}
<bytecode: 0x0000027338e5f8e8>
<environment: namespace:tidyselect>
在这种情况下,函数starts_with
是由dplyr使用NAMESPACE
文件附加的,在该文件中,您可以列出应该与包一起附加的其他包中的函数。您可以签入dplyr
源代码。
但是where
并没有像我们已经看到的那样以这种方式提供。在这种情况下,函数确实被引用,并且仅在tidyselect包中进行评估。如果查看cross的源代码,您会注意到在第82行中,列规范被传递到同一文件中定义的函数across_setup
。在该函数中,列规范被引用(第174175行(,然后发送到tidyselect
函数tidyselect::eval_select
(第177行(。该函数是tidyselect包的一部分,可以访问where
。