Site icon R-bloggers

Six not-so-basic base R functions

[This article was first published on %>% dreams, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

Leonetto Cappiello, Benedictine

R is known for its versatility and extensive collection of packages. As of the publishing of this post, there are over 23 thousand packages on R-universe. But what if I told you that you could do some pretty amazing things without loading any packages at all?

There’s a lot of love for base R, and I am excited to pile on. In this blog post, we will explore a few of my favorite “not-so-basic” (i.e., maybe new to you!) base R functions. Click ‘Run code’ in order to see them in action, made possible by webR and the quarto-webr extension!1

Note

This post includes examples from the base, graphics, datasets, and stats packages, which are automatically loaded when you open R. Additional base R packages include grDevices, utils, and methods.2

  1. invisible(): Return an invisible copy of an object
  2. noquote(): Print a character string without quotes
  3. coplot(): Visualize interactions
  4. nzchar(): Find out if elements of a character vector are non-empty strings
  5. with(): Evaluate an expression in a data environment
  6. Null coalescing operator %||%: Return first input if not NULL, otherwise return second input
< section id="invisible" class="level2 page-columns page-full">

1. invisible

The invisible() function “returns a temporarily invisible copy of an object” by hiding the output of a function in the console. When you wrap a function in invisible(), it will execute normally and can be assigned to a variable or used in other operations, but the result isn’t printed out.

Resources

Below are examples where the functions return their argument x, but one does so invisibly.

Please enable JavaScript to experience the dynamic code cell content on this page.
Please enable JavaScript to experience the dynamic code cell content on this page.

The way to see invisible output is by saving to a variable or running print(). Both of the below will print:

Please enable JavaScript to experience the dynamic code cell content on this page.

Let’s try another example. Run the chunk below to install the purrr and tidytab packages. Installing the CRAN version of purrr from the webR binary repository is as easy as calling webr::install(). The tidytab package is compiled into a WebAssembly binary on R-universe and needs the repos argument to find it. mount = FALSE is due to a bug in the Firefox WebAssembly interpreter. If you’re not using Firefox, then I suggest you try the code below with mount = TRUE! (Note: this might take a few seconds, and longer with mount = FALSE.)

Please enable JavaScript to experience the dynamic code cell content on this page.

Using purrr and tidytab::tab2() together results in two NULL list items we do not need.

Please enable JavaScript to experience the dynamic code cell content on this page.

Running invisible() eliminates that!

Please enable JavaScript to experience the dynamic code cell content on this page.

When writing a function, R can print a lot of stuff implicitly. Using invisible(), you can return results while controlling what is displayed to a user, avoiding cluttering the console with intermediate results.

Per the Tidyverse design guide, “if a function is called primarily for its side-effects, it should invisibly return a useful output.” In fact, many of your favorite functions use invisible(), such as readr::write_csv(), which invisibly returns the saved data frame.

< section id="noquote" class="level2 page-columns page-full">

2. noquote

The noquote() function “prints character strings without quotes.”

Resources

Please enable JavaScript to experience the dynamic code cell content on this page.
Please enable JavaScript to experience the dynamic code cell content on this page.

I use noquote() in a function url_make that converts Markdown reference-style links into HTML links. The input is a character string of a Markdown reference-style link mdUrl and the output is the HTML version of that URL. With noquote(), I can paste the output directly in my text.

Very proud of my little #rstats function to turn a Markdown URL to HTML ☺️ (and save it to your clipboard too). pic.twitter.com/TsddtTDn9R

— Isabella Velásquez (@ivelasq3) April 27, 2022

Try it out in an anonymous function below!

Learn more about this syntax in my previous blog post!

Please enable JavaScript to experience the dynamic code cell content on this page. < section id="coplot" class="level2 page-columns page-full">

3. coplot

The coplot() function creates conditioning plots, which are helpful in multivariate analysis. They allow you to explore pairs of variables conditioned on a third so you can understand how relationships change across different conditions.

Resources

The syntax of coplot() is coplot(y ~ x | a, data), where y and x are the variables you want to plot, a is the conditioning variable, and data is the data frame. The variables provided to coplot() can be either numeric or factors.

Using the built-in quakes dataset, let’s look at the relationship between the latitude (lat) and the longitude (long) and how it varies depending on the depth in km of seismic events (depth).

Please enable JavaScript to experience the dynamic code cell content on this page.

To interpret this plot:

The orientation of plots might not be the most intuitive. Set rows = 1 to make the coplot easier to read.

Please enable JavaScript to experience the dynamic code cell content on this page.

Here, you can see how the area of Fiji earthquakes grows smaller with increasing depth.

You can also condition on two variables with the syntax coplot(y ~ x| a * b), where the plots of y versus x are produced conditional on the two variables a and b. Below, the coplot shows the relationship with depth from left to right and the relationship with magnitude (mag) from top to bottom. Check out a more in-depth explanation of this plot on StackOverflow.

Please enable JavaScript to experience the dynamic code cell content on this page.

I first learned about coplot() thanks to Eric Leung’s tweet. Thanks, Eric!

TIL about coplots in base #RStats. in my nearly decade use of R, i've never come across this function to quickly explore pairs of variables conditioned on a third

library(palmerpenguins)
coplot(body_mass_g ~ bill_length_mm|species, data = penguins)https://t.co/EVpI738VzO pic.twitter.com/zcTw4HGvnZ

— Eric Leung 梁挺亮 (@erictleung) August 5, 2022
< section id="nzchar" class="level2 page-columns page-full">

4. nzchar

From the documentation, “nzchar() is a fast way to find out if elements of a character vector are non-empty strings”. It returns TRUE for non-empty strings and FALSE for empty strings. This function is particularly helpful when working with environment variables - see an example in the tuber documentation!

Resources

Please enable JavaScript to experience the dynamic code cell content on this page.
Please enable JavaScript to experience the dynamic code cell content on this page.

I have written about nzchar in the past and I’ve also explained how to create a GIF using asciicast!

TIL: nzchar(). Super useful when working with environment variables in R.

also, #asciicast is amazing! install the GIF converter with remotes::install_github('r-lib/asciicast', ref = remotes::github_pull(24)) #rstats h/t @GaborCsardi pic.twitter.com/pCZQLCNaDl

— Isabella Velásquez (@ivelasq3) May 11, 2022
< section id="with" class="level2 page-columns page-full">

5. with

If you use base R, you’ve likely encountered the dollar sign $ when evaluating expressions with variables from a data frame. The with() function lets you reference columns directly, eliminating the need to repeat the data frame name multiple times. This makes your code more concise and easier to read.

Resources

So, instead of writing plot(mtcars$hp, mtcars$mpg), you can write:

Please enable JavaScript to experience the dynamic code cell content on this page.

This is particularly handy to use with the base R pipe |>:

Please enable JavaScript to experience the dynamic code cell content on this page.

Michael Love’s Tweet shows how to connect a dplyr chain to a base plot function using with():

Please enable JavaScript to experience the dynamic code cell content on this page. < section id="lengths" class="level2 page-columns page-full">

6. lengths

lengths() is a more efficient version of sapply(df, length). length() determines the number of elements in an object, and lengths() will provide the lengths of elements across columns in the data frame.

Resources

Please enable JavaScript to experience the dynamic code cell content on this page.

Pretty straightforward but I think it is a neat function 🙂

< section id="null-coalescing-operator-in-r" class="level2">

7. Null-coalescing operator in R, %||%

OK, this one isn’t in base R – yet! In the upcoming release, R will automatically provide the null-coalescing operator, %||%. Per the release notes:

‘L %||% R’ newly in base is an expressive idiom for the ‘if(!is.null(L)) L else R’ or ‘if(is.null(L)) R else L’ phrases.

Or, in code:

`%||%` <- function(x, y) {
   if (is_null(x)) y else x
}

Essentially, this means: if the first (left-hand) input x is NULL, return y. If x is not NULL, return the input.

It was great to see Jenny Bryan and the R community celebrate the formal inclusion of the null-coalescing operator into the R language on Mastodon. The null-coalescing operator is particularly useful for R package developers, as highlighted by Jenny in her useR! 2018 keynote, used when the tidyverse team needs to assess whether an argument has been supplied, or if the default value which is commonly NULL has been passed, meaning that the default argument has been supplied.

Jenny Bryan’s Code smell and feels null-coalescing operator example


However, the null-coalescing operator can also be useful in interactive use, for functions that take NULL as a valid argument. In this case, if supplied in the argument itself it can yield different interesting behaviors. For example:

Please enable JavaScript to experience the dynamic code cell content on this page.

There’s more discussion about the utility of the function.

< section id="the-fun-ctions-never-stop" class="level2">

The fun-ctions never stop

Want even more functions (base R or not)? Here are some other resources to check out:

Thanks to all community members sharing their code and functions!

< section id="footnotes" class="footnotes footnotes-end-of-document">

Footnotes

  1. Many thanks to the following resources for making this post possible:

    ↩︎
  2. This is a handy guide for seeing the packages loaded in your R session!↩︎

To leave a comment for the author, please follow the link and comment on their blog: %>% dreams.

R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
Exit mobile version