How can library() accept both quoted and unquoted strings
Great question!
Let's crack open the library()
function to see how it works.
enter library
into your interactive session to see the innards of the function.
The key parts of the function are from lines 186 to 197.
if (!missing(package)) {
if (is.null(lib.loc))
lib.loc <- .libPaths()
lib.loc <- lib.loc[file.info(lib.loc)$isdir %in% TRUE]
if (!character.only)
package <- as.character(substitute(package))
if (length(package) != 1L)
stop("'package' must be of length 1")
if (is.na(package) || (package == ""))
stop("invalid package name")
pkgname <- paste("package", package, sep = ":")
newpackage <- is.na(match(pkgname, search()))
The key lines are
if (!character.only)
package <- as.character(substitute(package))
This means that as long as you don't change the character.only
argument of library to TRUE
, R will convert your package name into a character string and search for that.
Let's test:
> library(ggplot2,character.only=TRUE)
outputs:
Error in library(ggplot2, character.only = TRUE) :
object 'ggplot2' not found
whereas
library("ggplot2",character.only=TRUE)
loads the package.
Basically, no matter what you give the library()
function as an argument for package
it will convert it into a characters unless you specify character.only to be TRUE
.
As Dason points out in the comments, a good use of the character.only
argument is in cases where you have the library names stored as objects themselves.
How can you make tidyverse functions that support both quoted and unquoted arguments?
If it needs to work on both quoted/unquoted, use ensym
test_func <- function(variable) {
dplyr::count(mtcars, !!rlang::ensym(variable))
}
-testing
test_func(cyl)
# cyl n
#1 4 11
#2 6 7
#3 8 14
test_func('cyl')
# cyl n
#1 4 11
#2 6 7
#3 8 14
NOTE: Better to have data also as an argument to the function
Quote an unquoted text in R
str <- "ACOT13,BIRC6,BOD1L1,CALM3,CDC42,CEP350,CIAO1,CLTA,CLTC,DIAPH1,DYNC2I1,DYNLL1,HAUS8,INO80,KIF22,KIFC1,MAD1L1,MAPK1,NSFL1C,NUP62,PLK3,PRC1,PRPF19,RMDN3,SEPTIN2,TUBG1,WDR62"
result <- strsplit(str,",")
Make a function (which uses data.table) that supports both quoted and unquoted arguments and then works in purrr::map (or lapply)
We can use :
library(data.table)
col_count2 <- function(dt, ...){
vars <- NULL
tryCatch({vars <- list(...)[[1]]}, error = function(e) {})
if(!is.character(vars)) vars <- as.character(substitute(list(...))[-1])
dt[, .N, by = vars]
}
identical(col_count2(dt_iris, Petal.Width, Species),
col_count2(dt_iris, c('Petal.Width', 'Species')))
#[1] TRUE
purrr::map(colnames(dt_iris), col_count2, dt = dt_iris)
#[[1]]
# Sepal.Length N
# 1: 5.1 9
# 2: 4.9 6
# 3: 4.7 2
# 4: 4.6 4
#....
#[[2]]
# Sepal.Width N
# 1: 3.5 6
# 2: 3.0 26
# 3: 3.2 13
# 4: 3.1 11
#....
#....
The use of quotation marks when loading a package in R
This is an example of non-standard evaluation. I'm not sure there is "best practice" regarding whether you should put packages in quotes. But
- If you submit a paper to the Journal of Statistical Software they insist that package names are in quotes
- Advanced R programming gives the downsides and also suggests against it.
The argument against
library(MASS)
is that for new users, it's hard to guess what
pkg = "MASS"
library(pkg)
will do.
Error: Quosures can only be unquoted within a quasiquotation context
It may be better to use ensym
as we can pass either quoted or unquoted as input. The symbol is then converted to string with as_string
, then we use the base R
Extract
method ([[
) to extract the column as a vector to be used in wtd.chi.sq
xtab_func <- function(dat, col, target, wgt){
col <- rlang::as_string(ensym(col))
target <- rlang::as_string(ensym(target))
wgt <- rlang::as_string(ensym(wgt))
wtd.chi.sq(dat[[target]],dat[[col]], weight = dat[[wgt]])
}
-testing
xtab_func(data_in, 'Q50_1','pov','wgt1')
Chisq df p.value
7.3395092 4.0000000 0.1189981
xtab_func(data_in, Q50_1, pov, wgt1)
Chisq df p.value
7.3395092 4.0000000 0.1189981
NOTE: The dataset passed into the function is not quoted
How to properly pass quoted strings as part of URL input to httr:GET()?
I tried to find posts that covered this already, but there's a little detail here that threw me off. You can use utils::URLencode
the encode the URL so that the quotation marks will be replaced with their percent-encoded equivalents.
URLencode
has an argument repeated
, which defaults to false:
repeated—logical: should apparently already-encoded URLs be encoded again?
An ‘apparently already-encoded URL’ is one containing %xx for two hexadecimal digits.
Your URL already has one piece encoded with %3A
, the encoded version of :
; because an encoded substring already exists, no further encoding is done by default. Instead, set repeated = FALSE
, and the quotation marks get encoded as well:
library(httr)
urlinp <- 'https://www.uniprot.org/uniprot/?query=name%3A"dna+methyltransferase"'
URLencode(urlinp, repeated = FALSE)
#> [1] "https://www.uniprot.org/uniprot/?query=name%3A\"dna+methyltransferase\""
URLencode(urlinp, repeated = TRUE)
#> [1] "https://www.uniprot.org/uniprot/?query=name%253A%22dna+methyltransferase%22"
status_code(GET(URLencode(urlinp, repeated = TRUE)))
#> [1] 200
Syntax for loading vs. installing libraries.
library
function takes package name
as first argument. This name
actually refers to the name passed as package argument rather than any value associated to that name. library
function internally converts the package argument to a character literal (except when character.only
is set to TRUE
).
So,
plyr <- "dplyr"
library(plyr)
will undergo
if(!character.only)
package <- as.character(substitute(plyr))
to become
package <- "plyr"
install.packages
takes a character vector as name(s) of packages to be installed.
dd <- "plyr"
install.packages(dd)
This would install plyr
.
It is becauseinstall.packages
don't do any such conversion with pkgs
argument. So install.packages
installs what pkgs
refers to.
Related Topics
How to Replace Numeric Codes with Value Labels from a Lookup Table
Voronoi Diagram Polygons Enclosed in Geographic Borders
How to Use Aws Cli to Only Copy Files in S3 Bucket That Match a Given String Pattern
Read-Write Pipe() Communication in R
Ellipse Containing Percentage of Given Points in R
Setting Hex Bins in Ggplot2 to Same Size
Removing a List of Columns from a Data.Frame Using Subset
Produce an Inset in Each Facet of an R Ggplot While Preserving Colours of the Original Facet Content
R Map Switzerland According to Npa (Locality)
Shiny R - Download the Result of a Table
Find *All* Duplicated Records in Data.Table (Not All-But-One)
Fill Area Between Two Lines, with High/Low and Dates
Generating a Very Large Matrix of String Combinations Using Combn() and Bigmemory Package
R: Creating a Map of Selected Canadian Provinces and U.S. States
References Truncated in Beamer Presentation Prepared in Knitr/Rmarkdown
Shiny: Open New Browser Tab from Within Shiny App
How to Determine the Geom Type of Each Layer of a Ggplot2 Object