Named and positional arguments

Published

November 16, 2023

library(palmerpenguins)
library(ggplot2)

Consider the following code we use to create a scatterplot from the penguin data:

ggplot(data = penguins,
       mapping = aes(x = body_mass_g, y = flipper_length_mm)) +
    geom_point()
Warning: Removed 2 rows containing missing values or values outside the scale range
(`geom_point()`).

We use the data and mapping arguments in the ggplot() function to define the input data and the aesthetic mappings, respectively. When constructing this code, we explicitly write the names of arguments (e.g. data = ...). This is called using named arguments.

Compare this to the following code, which generates the exact same scatterplot:

ggplot(penguins,
       aes(x = body_mass_g, y = flipper_length_mm)) +
    geom_point()
Warning: Removed 2 rows containing missing values or values outside the scale range
(`geom_point()`).

Why do you think this works? Hint: look at the ‘Usage’ section on the help page for ggplot()

When we don’t provide the names of arguments, R uses their positions in the function call to identify which values to assign to which argument. This is called using positional arguments. You can find the order of arguments that R expects for a function by referring to the help documentation, or by using the args() function.

args(ggplot)
function (data = NULL, mapping = aes(), ..., environment = parent.frame()) 
NULL

Now that we’ve seen the order of the arguments the ggplot() function expects, let’s re-examine the second block of code we used to create the scatterplot.

ggplot(penguins,
       aes(x = body_mass_g, y = flipper_length_mm)) +
    geom_point()

The first argument the ggplot() function expects in the data argument. In this code, penguins is the first argument we provide. Since we didn’t specify an argument name, R automatically assigns it to the data argument. Similarly, the aesthetic mapping (aes(...)) is the second argument we provide. Again, we didn’t specify an argument name so R automatically assigns it to mapping, the next unused argument in list of arguments returned by the args(ggplot).

Both argument conventions offer advantages. When we use named arguments, we can provide them in any order.

ggplot(mapping = aes(x = body_mass_g, y = flipper_length_mm),
       data = penguins) +
    geom_point()

Positional arguments save us some typing and make use more efficient programmers, particularly for functions that we re-use often in our code. For example, since the first argument for most dplyr functions is the input data, we tend define the data using a positional argument.

We can also use a mix of named and positional arguments in the same function call:

ggplot(aes(x = body_mass_g, y = flipper_length_mm),
       data = penguins) +
    geom_point()

Even though the mapping aes() is the first positional argument R assigns it to the mapping argument. This is because we’ve explicitly defined the data as a named argument elsewhere in the function call. When R assigns positional arguments, it first assigns all of the named arguments, then assigns positional arguments to whatever is left. In the above example, when R goes to assign the aesthetics it skips the data argument, because we define data using a named argument, and assigns aes(...) to the next mapping, which is the next un-used argument after data.

R version 4.4.0 (2024-04-24 ucrt)
Platform: x86_64-w64-mingw32/x64
Running under: Windows 10 x64 (build 19045)

Matrix products: default


locale:
[1] LC_COLLATE=English_United States.utf8 
[2] LC_CTYPE=English_United States.utf8   
[3] LC_MONETARY=English_United States.utf8
[4] LC_NUMERIC=C                          
[5] LC_TIME=English_United States.utf8    

time zone: America/New_York
tzcode source: internal

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] ggplot2_3.5.1        palmerpenguins_0.1.1

loaded via a namespace (and not attached):
 [1] vctrs_0.6.5       cli_3.6.2         knitr_1.47        rlang_1.1.3      
 [5] xfun_0.44         generics_0.1.3    jsonlite_1.8.8    labeling_0.4.3   
 [9] glue_1.7.0        colorspace_2.1-0  htmltools_0.5.8.1 scales_1.3.0     
[13] fansi_1.0.6       rmarkdown_2.27    grid_4.4.0        evaluate_0.23    
[17] munsell_0.5.1     tibble_3.2.1      fastmap_1.2.0     yaml_2.3.8       
[21] lifecycle_1.0.4   compiler_4.4.0    dplyr_1.1.4       htmlwidgets_1.6.4
[25] pkgconfig_2.0.3   rstudioapi_0.16.0 farver_2.1.2      digest_0.6.35    
[29] R6_2.5.1          tidyselect_1.2.1  utf8_1.2.4        pillar_1.9.0     
[33] magrittr_2.0.3    withr_3.0.0       tools_4.4.0       gtable_0.3.5     
Back to top