rlang: форма назначения кво, документация, нахождение. Или что-то

Многие примеры страниц справки для quo принимают формы, подобные этой, присваивая вывод quo quo:

quo <- quo(letters)
quo <- quo(toupper(!! quo))
quo
eval_tidy(quo)

Кажется очевидным, что эти назначения не перезаписывают функцию кво (поскольку он делает это дважды подряд), как обычно. Первоклассные объекты и все такое.

Поэтому мое лучшее предположение о том, что происходит, заключается в том, что это не обычное назначение, а форма назначения quo, quo<-. Но я не смог никакой информации об этом.

непродуктивные:

getAnywhere (кво<-)
getAnywhere(`кво<-`)
getAnywhere(`quo <-`)
rlang::: кво<-
rlang:::`кво<-`
rlang:::`quo <-`

Поэтому я хотел бы, чтобы кто-нибудь рассказал мне, для чего предназначена форма назначения и как она работает, и даже более того, если я вижу не форму назначения, а скорее какой-то аспект довольно гномичного "[q]uo self-оценка в собственной среде ".

Наконец, если где-то есть доступная документация по этой функции или использованию, я хотел бы знать, как я мог бы ее найти, а если нет, то, вероятно, я должен сообщить об этом Хэдли. То, как он держит столько тарелок, вращая их, не уронив больше шариков, чем он, - для меня загадка.

1 ответ

Решение
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 в .GlobalEnvнайдите его там (цитата, которую вы только что создали) и остановитесь:

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, но его окружающая среда, а именно. где он собирается начать свой собственный поиск, когда он называется. Смотрите карту мира: http://blog.obeautifulcode.com/img/how-r-searches-and-finds-stuff/map-of-the-world.png источник: Сурадж Гупта 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 быть умным и напрямую использовать парены, R будет знать, что он должен искать функцию, вот что делается в:

quo <- quo(toupper(!! quo))

(Также сравните:

> bar
Error: object 'bar' not found
> bar()
Error in bar() : could not find function "bar"

Сообщения об ошибках намекают на то, что R не может найти / найти, с паренсами и без них.)


Теперь ради интереса, давайте прикрепим весь тидиверс:

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 от 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 
Другие вопросы по тегам