From c7a81ec3ef518bf17273ce8f1bdcafdaef293c0f Mon Sep 17 00:00:00 2001 From: DominikRafacz Date: Thu, 2 Feb 2023 09:26:19 +0100 Subject: [PATCH 1/9] temp content --- .../index.Rmd | 126 ++++++++++++++++++ .../index.html | 101 ++++++++++++++ 2 files changed, 227 insertions(+) create mode 100644 content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/index.Rmd create mode 100644 content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/index.html diff --git a/content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/index.Rmd b/content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/index.Rmd new file mode 100644 index 0000000..92c7fa5 --- /dev/null +++ b/content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/index.Rmd @@ -0,0 +1,126 @@ +--- +title: 'R Basic Advanceds: Variables and Names in dplyr' +author: Dominik Rafacz +date: '2023-01-30' +slug: r-basic-advanceds-variables-and-names-in-dplyr +categories: ['Tutorial'] +tags: ['r', 'tutorial', 'dplyr', 'environments', 'rlang'] +--- + +# Intro + +Hello everyone! We've had quite a long hiatus caused by various life things (including graduating from college, changing jobs and lawsuits), but we're back and want to bring the blog back to life. And since the basics of advanced methods is what interests me the most, today I'm going to introduce you to a post about something that sooner or later every dplyr user will encounter. + +```{r message=FALSE, warning=FALSE, include=FALSE} +library(dplyr) +iris <- iris %>% slice(1:5) +``` + +# Problem 1: symbols treated as names vs variables containing strings with names + +dplyr verbs are very convenient, because we can use *symbols* instead of constantly accessing the data with *strings with names*. E.g. compare the code for selecting columns in data frame in base R and in dplyr: + +```{r eval=FALSE} +# base +iris[, c("Sepal.Length", "Sepal.Width")] + +# dplyr +iris %>% + select(Sepal.Length, Sepal.Width) +``` + +We can see the clear difference between the base style and the dplyr style: + +* `"Sepal.Length", "Sepal.Width"` -- strings with names, they are quoted by " or ' +* `Sepal.Length, Sepal.Width` -- symbols, they are not quoted (or quoted using \` character, if they contain spaces) + +In the second case *symbols* are used to access columns in data.frame (it is not important how that works in details, we will take care of that in another post). It is crucial to know this difference and understand it, as it might help us not to fall into the traps which I will discuss in the rest of the post. + +dplyr introduced this syntax, because it is simpler. Less characters to type is always nice, especially when we are using column names really often, which usually is the case. + +Sometimes, however, we do not know names of columns to select in advance. E.g., we have an external variable containing names of columns to select, like this: + +```{r} +my_variables <- c("Sepal.Length", "Sepal.Width") +``` + +We can provide it to `select` directly: + +```{r warning=TRUE} +iris %>% + select(my_variables) +``` + +but it throws a warning. tidyverse boasts detailed messages and it is worth always taking them into consideration. This is not recommended, as it is ambiguous. We can easily imagine situation when there is a column in data called "my_variables". What should happen, if we have both such a column and such an external variable? Which one would be selected? The answer does not matter for us, as we want to stick to best practices. + +A solution suggested by authors of dplyr is to use `dplyr::all_of()`, which explicitly transforms a vector of names (or a single name) into symbols. In this way there is no ambiguity -- dplyr knows that it should use columns named by vector `my_variables`, not use `my_variables` as a name of column. + +```{r warning=TRUE} +iris %>% + select(all_of(my_variables)) +``` + +## Problem 2: passing columns as arguments to custom functions + +This difference between passing a variable name vs or symbol as a name can be especially tricky when building a function which calls dplyr verbs inside of it and is parametrized by column names. Let's see an example: + +```{r} +my_subset <- function(data, my_var) { + data %>% + select(my_var) +} +``` + + +This might cause a lot of issues. Should we provide a string as a name (`my_subset(iris, "Sepal.Length")`) or a symbol (`my_subset(iris, Sepal.Length)`)? To answer this question, we should first be clear about our intent (it would be nice to write a few words of documentation -- for other users or for ourselves in the future). Both approaches are possible, but it is better to stick to one. + +If we decide that we want to use names as a string (it is a common case, e.g. when building shiny app and columns are selected in inputs), then we should use previously shown trick with `dplyr::all_of()`: + + +```{r, eval=FALSE} +my_subset_with_strings <- function(data, my_var_as_string) { + data %>% + select(all_of(my_var_as_string)) +} + +my_subset_with_strings(iris, c("Sepal.Length", "Sepal.Width")) +``` + +If we want to use symbols, just like directly in dplyr functions (mostly when those columns to use are predefined, in our internal functions or analyses), we have to *embrace* the variable: + +```{r, eval=FALSE} +my_subset_with_symbols <- function(data, my_var_as_symbol) { + data %>% + select({{ my_var_as_symbol }}) +} + +my_subset_with_symbols(iris, Petal.Length) + +my_subset_with_symbols(iris, Petal.Length, Sepal.Width) + +iris %>% + select(Petal.Length) + +iris %>% + select(Petal.Length, Sepal.Width) + + +my_var_as_symbol = Petal.Length +iris %>% + select(my_var_as_symbol) + +``` + +In this way we let dplyr know that `my_var_as_symbol` has to be passed directly as user provided it. We can think of embracing as of cut-paste operation. We tell dplyr: "Take what user provided in place of `my_var_as_symbol` in function call and plug it directly into `select`, without creating any intermediate variables.". Call to `my_subset_with_symbols()` is basically replaced with what lies inside of it. You can see comparison in figure TODO. + +# Problem 3: dynamic columns in purrr formulas in `across` + +Solutions above work fine when we provide those column names to `dplyr::select()`, `dplyr::filter()` or `dplyr::group_by()` directly. But sometimes we need a function that does something more. Let's say we want to have a function `do_magic`, which takes as an input some data, name of column `special` and names of other columns `others`. This function subtracts column `special` from all columns `others`. + +We can try to do it with `dplyr::mutate(dplyr::across())`. It has a syntax `mutate(across(columns_to_mutate, function_to_apply))`. If we want to provide a custom unnamed function, we can use *purrr formula syntax*: `~ expression with .x` where `.x` is column. This (without enclosing it in a function yet) could look like: + +```{r, eval=FALSE} +iris %>% + mutate(across(all_of(c("Sepal.Length", "Sepal.Width")), ~ .x - Petal.Length)) + +``` diff --git a/content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/index.html b/content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/index.html new file mode 100644 index 0000000..3bc6327 --- /dev/null +++ b/content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/index.html @@ -0,0 +1,101 @@ +--- +title: 'R Basic Advanceds: Variables and Names in dplyr' +author: Dominik Rafacz +date: '2023-01-30' +slug: r-basic-advanceds-variables-and-names-in-dplyr +categories: ['Tutorial'] +tags: ['r', 'tutorial', 'dplyr', 'environments', 'rlang'] +--- + + + +
+

Intro

+

Hello everyone! We’ve had quite a long hiatus caused by various life things (including graduating from college, changing jobs and lawsuits), but we’re back and want to bring the blog back to life. And since the basics of advanced methods is what interests me the most, today I’m going to introduce you to a post about something that sooner or later every dplyr user will encounter.

+
+
+

Problem 1: symbols treated as names vs variables containing strings with names

+

dplyr verbs are very convenient, because we can use symbols instead of constantly accessing the data with strings with names. E.g. compare the code for selecting columns in data frame in base R and in dplyr:

+
# base
+iris[, c("Sepal.Length", "Sepal.Width")]
+
+# dplyr
+iris %>%
+  select(Sepal.Length, Sepal.Width)
+

We can see the clear difference between the base style and the dplyr style:

+ +

In the second case symbols are used to access columns in data.frame (it is not important how that works in details, we will take care of that in another post). It is crucial to know this difference and understand it, as it might help us not to fall into the traps which I will discuss in the rest of the post.

+

dplyr introduced this syntax, because it is simpler. Less characters to type is always nice, especially when we are using column names really often, which usually is the case.

+

Sometimes, however, we do not know names of columns to select in advance. E.g., we have an external variable containing names of columns to select, like this:

+
my_variables <- c("Sepal.Length", "Sepal.Width")
+

We can provide it to select directly:

+
iris %>%
+  select(my_variables)
+
## Note: Using an external vector in selections is ambiguous.
+## i Use `all_of(my_variables)` instead of `my_variables` to silence this message.
+## i See <https://tidyselect.r-lib.org/reference/faq-external-vector.html>.
+## This message is displayed once per session.
+
##   Sepal.Length Sepal.Width
+## 1          5.1         3.5
+## 2          4.9         3.0
+## 3          4.7         3.2
+## 4          4.6         3.1
+## 5          5.0         3.6
+

but it throws a warning. tidyverse boasts detailed messages and it is worth always taking them into consideration. This is not recommended, as it is ambiguous. We can easily imagine situation when there is a column in data called “my_variables”. What should happen, if we have both such a column and such an external variable? Which one would be selected? The answer does not matter for us, as we want to stick to best practices.

+

A solution suggested by authors of dplyr is to use dplyr::all_of(), which explicitly transforms a vector of names (or a single name) into symbols. In this way there is no ambiguity – dplyr knows that it should use columns named by vector my_variables, not use my_variables as a name of column.

+
iris %>%
+  select(all_of(my_variables))
+
##   Sepal.Length Sepal.Width
+## 1          5.1         3.5
+## 2          4.9         3.0
+## 3          4.7         3.2
+## 4          4.6         3.1
+## 5          5.0         3.6
+
+

Problem 2: passing columns as arguments to custom functions

+

This difference between passing a variable name vs or symbol as a name can be especially tricky when building a function which calls dplyr verbs inside of it and is parametrized by column names. Let’s see an example:

+
my_subset <- function(data, my_var) {
+  data %>%
+    select(my_var)
+}
+

This might cause a lot of issues. Should we provide a string as a name (my_subset(iris, "Sepal.Length")) or a symbol (my_subset(iris, Sepal.Length))? To answer this question, we should first be clear about our intent (it would be nice to write a few words of documentation – for other users or for ourselves in the future). Both approaches are possible, but it is better to stick to one.

+

If we decide that we want to use names as a string (it is a common case, e.g. when building shiny app and columns are selected in inputs), then we should use previously shown trick with dplyr::all_of():

+
my_subset_with_strings <- function(data, my_var_as_string) {
+  data %>%
+    select(all_of(my_var_as_string))
+}
+
+my_subset_with_strings(iris, c("Sepal.Length", "Sepal.Width"))
+

If we want to use symbols, just like directly in dplyr functions (mostly when those columns to use are predefined, in our internal functions or analyses), we have to embrace the variable:

+
my_subset_with_symbols <- function(data, my_var_as_symbol) {
+  data %>%
+    select({{ my_var_as_symbol }})
+}
+
+my_subset_with_symbols(iris, Petal.Length)
+
+my_subset_with_symbols(iris, Petal.Length, Sepal.Width)
+
+iris %>%
+  select(Petal.Length)
+
+iris %>%
+  select(Petal.Length, Sepal.Width)
+
+
+my_var_as_symbol = Petal.Length
+iris %>%
+  select(my_var_as_symbol)
+

In this way we let dplyr know that my_var_as_symbol has to be passed directly as user provided it. We can think of embracing as of cut-paste operation. We tell dplyr: “Take what user provided in place of my_var_as_symbol in function call and plug it directly into select, without creating any intermediate variables.”. Call to my_subset_with_symbols() is basically replaced with what lies inside of it. You can see comparison in figure TODO.

+
+
+
+

Problem 3: dynamic columns in purrr formulas in across

+

Solutions above work fine when we provide those column names to dplyr::select(), dplyr::filter() or dplyr::group_by() directly. But sometimes we need a function that does something more. Let’s say we want to have a function do_magic, which takes as an input some data, name of column special and names of other columns others. This function subtracts column special from all columns others.

+

We can try to do it with dplyr::mutate(dplyr::across()). It has a syntax mutate(across(columns_to_mutate, function_to_apply)). If we want to provide a custom unnamed function, we can use purrr formula syntax: ~ expression with .x where .x is column. This (without enclosing it in a function yet) could look like:

+
iris %>%
+  mutate(across(all_of(c("Sepal.Length", "Sepal.Width")), ~ .x - Petal.Length))
+
From bc143a062c6efebf251181b121394bbbff3bd35a Mon Sep 17 00:00:00 2001 From: DominikRafacz Date: Sun, 3 Sep 2023 20:21:55 +0200 Subject: [PATCH 2/9] rework content of the article --- .../index.Rmd | 265 ++-- .../index.html | 217 +-- .../selection-ambiguity.png | Bin 0 -> 132392 bytes .../selection-ambiguity.svg | 1239 +++++++++++++++++ 4 files changed, 1494 insertions(+), 227 deletions(-) create mode 100644 content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/selection-ambiguity.png create mode 100644 content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/selection-ambiguity.svg diff --git a/content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/index.Rmd b/content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/index.Rmd index 92c7fa5..c39711f 100644 --- a/content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/index.Rmd +++ b/content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/index.Rmd @@ -1,126 +1,139 @@ ---- -title: 'R Basic Advanceds: Variables and Names in dplyr' -author: Dominik Rafacz -date: '2023-01-30' -slug: r-basic-advanceds-variables-and-names-in-dplyr -categories: ['Tutorial'] -tags: ['r', 'tutorial', 'dplyr', 'environments', 'rlang'] ---- - -# Intro - -Hello everyone! We've had quite a long hiatus caused by various life things (including graduating from college, changing jobs and lawsuits), but we're back and want to bring the blog back to life. And since the basics of advanced methods is what interests me the most, today I'm going to introduce you to a post about something that sooner or later every dplyr user will encounter. - -```{r message=FALSE, warning=FALSE, include=FALSE} -library(dplyr) -iris <- iris %>% slice(1:5) -``` - -# Problem 1: symbols treated as names vs variables containing strings with names - -dplyr verbs are very convenient, because we can use *symbols* instead of constantly accessing the data with *strings with names*. E.g. compare the code for selecting columns in data frame in base R and in dplyr: - -```{r eval=FALSE} -# base -iris[, c("Sepal.Length", "Sepal.Width")] - -# dplyr -iris %>% - select(Sepal.Length, Sepal.Width) -``` - -We can see the clear difference between the base style and the dplyr style: - -* `"Sepal.Length", "Sepal.Width"` -- strings with names, they are quoted by " or ' -* `Sepal.Length, Sepal.Width` -- symbols, they are not quoted (or quoted using \` character, if they contain spaces) - -In the second case *symbols* are used to access columns in data.frame (it is not important how that works in details, we will take care of that in another post). It is crucial to know this difference and understand it, as it might help us not to fall into the traps which I will discuss in the rest of the post. - -dplyr introduced this syntax, because it is simpler. Less characters to type is always nice, especially when we are using column names really often, which usually is the case. - -Sometimes, however, we do not know names of columns to select in advance. E.g., we have an external variable containing names of columns to select, like this: - -```{r} -my_variables <- c("Sepal.Length", "Sepal.Width") -``` - -We can provide it to `select` directly: - -```{r warning=TRUE} -iris %>% - select(my_variables) -``` - -but it throws a warning. tidyverse boasts detailed messages and it is worth always taking them into consideration. This is not recommended, as it is ambiguous. We can easily imagine situation when there is a column in data called "my_variables". What should happen, if we have both such a column and such an external variable? Which one would be selected? The answer does not matter for us, as we want to stick to best practices. - -A solution suggested by authors of dplyr is to use `dplyr::all_of()`, which explicitly transforms a vector of names (or a single name) into symbols. In this way there is no ambiguity -- dplyr knows that it should use columns named by vector `my_variables`, not use `my_variables` as a name of column. - -```{r warning=TRUE} -iris %>% - select(all_of(my_variables)) -``` - -## Problem 2: passing columns as arguments to custom functions - -This difference between passing a variable name vs or symbol as a name can be especially tricky when building a function which calls dplyr verbs inside of it and is parametrized by column names. Let's see an example: - -```{r} -my_subset <- function(data, my_var) { - data %>% - select(my_var) -} -``` - - -This might cause a lot of issues. Should we provide a string as a name (`my_subset(iris, "Sepal.Length")`) or a symbol (`my_subset(iris, Sepal.Length)`)? To answer this question, we should first be clear about our intent (it would be nice to write a few words of documentation -- for other users or for ourselves in the future). Both approaches are possible, but it is better to stick to one. - -If we decide that we want to use names as a string (it is a common case, e.g. when building shiny app and columns are selected in inputs), then we should use previously shown trick with `dplyr::all_of()`: - - -```{r, eval=FALSE} -my_subset_with_strings <- function(data, my_var_as_string) { - data %>% - select(all_of(my_var_as_string)) -} - -my_subset_with_strings(iris, c("Sepal.Length", "Sepal.Width")) -``` - -If we want to use symbols, just like directly in dplyr functions (mostly when those columns to use are predefined, in our internal functions or analyses), we have to *embrace* the variable: - -```{r, eval=FALSE} -my_subset_with_symbols <- function(data, my_var_as_symbol) { - data %>% - select({{ my_var_as_symbol }}) -} - -my_subset_with_symbols(iris, Petal.Length) - -my_subset_with_symbols(iris, Petal.Length, Sepal.Width) - -iris %>% - select(Petal.Length) - -iris %>% - select(Petal.Length, Sepal.Width) - - -my_var_as_symbol = Petal.Length -iris %>% - select(my_var_as_symbol) - -``` - -In this way we let dplyr know that `my_var_as_symbol` has to be passed directly as user provided it. We can think of embracing as of cut-paste operation. We tell dplyr: "Take what user provided in place of `my_var_as_symbol` in function call and plug it directly into `select`, without creating any intermediate variables.". Call to `my_subset_with_symbols()` is basically replaced with what lies inside of it. You can see comparison in figure TODO. - -# Problem 3: dynamic columns in purrr formulas in `across` - -Solutions above work fine when we provide those column names to `dplyr::select()`, `dplyr::filter()` or `dplyr::group_by()` directly. But sometimes we need a function that does something more. Let's say we want to have a function `do_magic`, which takes as an input some data, name of column `special` and names of other columns `others`. This function subtracts column `special` from all columns `others`. - -We can try to do it with `dplyr::mutate(dplyr::across())`. It has a syntax `mutate(across(columns_to_mutate, function_to_apply))`. If we want to provide a custom unnamed function, we can use *purrr formula syntax*: `~ expression with .x` where `.x` is column. This (without enclosing it in a function yet) could look like: - -```{r, eval=FALSE} -iris %>% - mutate(across(all_of(c("Sepal.Length", "Sepal.Width")), ~ .x - Petal.Length)) - -``` +--- +title: 'R Basic Advanceds: Variables and Names in dplyr' +author: Dominik Rafacz +date: '2023-01-30' +slug: r-basic-advanceds-variables-and-names-in-dplyr +categories: ['Tutorial'] +tags: ['r', 'tutorial', 'dplyr', 'environments', 'rlang'] +--- + +# Intro + +Hello everyone! After an extended hiatus for various reasons (from graduating college to navigating job changes and legal challenges), we're back and eager to breathe new life into this blog. Given my deep interest in the fundamentals of advanced methods, today we're delving into an essential topic every dplyr user will eventually face. + +dplyr is meticulously designed with the primary goal of making code workflows read as naturally and close to plain language as possible. This design philosophy manifests in two critical dimensions: *semantic* and *syntactic*. + +Semantically, the emphasis is on **employing words with intuitive and easily understood meanings**. For instance, dplyr and its friends adhere to a robust naming convention where function names typically take on verb forms, elucidating the action they perform. + +Syntactically, the **arrangement and combination of these descriptive words is paramount**. Arguably, this is even more critical to the user experience. One of the most evident manifestations of this syntactical approach is the tidyverse's hallmark feature: **the pipe operator**. But we are not going to tackle this today. I will look into caveats of another essential and intuitive syntactic feature: the **use of symbols instead of strings to refer to variables within datasets**. This offers a more natural-feeling mode of interaction but, as I have found out over many years of using R, this feature can lead to some problems. + + +```{r message=FALSE, warning=FALSE, include=FALSE} +library(dplyr) +iris <- iris %>% slice(1:5) +``` + +# Problem 1: Symbols vs. strings with names + +Let's compare how we select columns in a data frame using base R versus dplyr: + +```{r eval=FALSE} +# base +iris[, c("Sepal.Length", "Sepal.Width")] + +# dplyr +iris %>% + select(Sepal.Length, Sepal.Width) +``` + +Notice the difference: + +* In base R, we use `"Sepal.Length", "Sepal.Width"`, which are **strings** enclosed in quotes (single and double quotes are both valid). +* With dplyr, we have `Sepal.Length, Sepal.Width`, unquoted **symbols**. + +In the second case *symbols* are used to access columns in a data frame, just like we use symbols to access any variable or function that we store in our top-level environments. +It is vital to grasp this distinction to sidestep potential pitfalls. which I will discuss in the rest of the post. + +So, what symbols actually are? We use them as names of objects and this is the identity of their core. This is why it feels natural to use them to not only access top-level variables, but also variables in data. There is more to the nature of symbols, but we will come back to that later. + +Notice that dplyr is smart enough to let you select variables by strings as well: + +```{r} +iris %>% + select("Sepal.Length", "Sepal.Width") +``` + +This is, however, inadvisable, as this is exactly what tidyverse designers wanted to avoid. + +Now, consider a scenario where we have an external variable storing column names: + +```{r} +my_variables <- c("Sepal.Length", "Sepal.Width") +``` + +Although it might seem intuitive to directly supply it to select: + +```{r warning=TRUE} +iris %>% + select(my_variables) +``` + +This generates a warning. Given the tidyverse's informative error messages, it's wise to pay heed. Directly supplying can be ambiguous —- imagine having a column named "my_variables". Which should be selected if we have both the column and the external variable? + + +![Diagram showing the dillema that dplyr is faced with when we torment it with ambiguous selections.](/images/selection-ambiguity.png) +To ensure clarity, dplyr authors suggest using dplyr::all_of(), which explicitly converts a name vector into symbols, resolving any ambiguities. + +```{r warning=TRUE} +iris %>% + select(all_of(my_variables)) +``` + +## Problem 2: Passing column names as arguments to custom functions + +Differentiating between passing a variable name or a symbol becomes trickier when constructing functions that internally use dplyr verbs. Consider: + +```{r} +my_subset <- function(data, my_var) { + data %>% + select(my_var) +} +``` + +This might cause a lot of issues. Should we provide a string as a name (`my_subset(iris, "Sepal.Length")`) or a symbol (`my_subset(iris, Sepal.Length)`)? To answer this question, **we should first be clear about our intent** (it would be nice to write a few words of documentation -- for other users or for ourselves in the future). **Both approaches are possible and valid**. It is important to **choose one and remain consistent** across all functions that we write. + +For instances where column names are passed as strings (common in Shiny apps when columns are selected by some input), one could utilize the previously discussed `dplyr::all_of()`: + + +```{r, eval=FALSE} +my_subset_with_strings <- function(data, my_var_as_string) { + data %>% + select(all_of(my_var_as_string)) +} + +my_subset_with_strings(iris, c("Sepal.Length", "Sepal.Width")) +``` + +If we want to use symbols, just like directly in dplyr functions (mostly when those columns to use are predefined, in our internal functions or analyses), we have to *embrace* the variable: + +```{r, eval=FALSE} +my_subset_with_symbols <- function(data, my_var_as_symbol) { + data %>% + select({{ my_var_as_symbol }}) +} + +my_subset_with_symbols(iris, Petal.Length) + +my_subset_with_symbols(iris, Petal.Length, Sepal.Width) +``` + +In this way we let dplyr know that `my_var_as_symbol` has to be passed directly as user provided it. We can think of embracing as of cut-paste operation. We tell dplyr: "Take what user provided in place of `my_var_as_symbol` in function call and plug it directly into `select`, without creating any intermediate variables.". Call to `my_subset_with_symbols()` is basically replaced with what lies inside of it. + +# Problem 3: dynamic columns in purrr formulas in `across` + +While the above solutions work seamlessly with functions like `dplyr::select()`, challenges arise when operations grow complex. Suppose we wish to craft a function, `do_magic`, that takes data, a special `column`, and several `others` columns. This function should add the special column to all others. + +Leveraging `dplyr::mutate(dplyr::across())` can achieve this. Its syntax is: + +```{r eval=FALSE} +mutate(across(columns_to_mutate, function_to_apply)) +``` + +For custom, unnamed functions, the *purrr formula syntax* (`~ expression` with `.x`) is beneficial. In our case (without enclosing it in a function yet) could look like: + +```{r, eval=FALSE} +iris %>% + mutate(across(all_of(c("Sepal.Length", "Sepal.Width")), ~ .x - Petal.Length)) +``` + +However, contrary to most languages, in R **symbols can be treated as objects themselves**. This allows dplyr to even perform such simplifications. The details are irrelevant now diff --git a/content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/index.html b/content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/index.html index 3bc6327..6835e05 100644 --- a/content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/index.html +++ b/content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/index.html @@ -1,101 +1,116 @@ ---- -title: 'R Basic Advanceds: Variables and Names in dplyr' -author: Dominik Rafacz -date: '2023-01-30' -slug: r-basic-advanceds-variables-and-names-in-dplyr -categories: ['Tutorial'] -tags: ['r', 'tutorial', 'dplyr', 'environments', 'rlang'] ---- - - - -
-

Intro

-

Hello everyone! We’ve had quite a long hiatus caused by various life things (including graduating from college, changing jobs and lawsuits), but we’re back and want to bring the blog back to life. And since the basics of advanced methods is what interests me the most, today I’m going to introduce you to a post about something that sooner or later every dplyr user will encounter.

-
-
-

Problem 1: symbols treated as names vs variables containing strings with names

-

dplyr verbs are very convenient, because we can use symbols instead of constantly accessing the data with strings with names. E.g. compare the code for selecting columns in data frame in base R and in dplyr:

-
# base
-iris[, c("Sepal.Length", "Sepal.Width")]
-
-# dplyr
-iris %>%
-  select(Sepal.Length, Sepal.Width)
-

We can see the clear difference between the base style and the dplyr style:

-
    -
  • "Sepal.Length", "Sepal.Width" – strings with names, they are quoted by ” or ’
  • -
  • Sepal.Length, Sepal.Width – symbols, they are not quoted (or quoted using ` character, if they contain spaces)
  • -
-

In the second case symbols are used to access columns in data.frame (it is not important how that works in details, we will take care of that in another post). It is crucial to know this difference and understand it, as it might help us not to fall into the traps which I will discuss in the rest of the post.

-

dplyr introduced this syntax, because it is simpler. Less characters to type is always nice, especially when we are using column names really often, which usually is the case.

-

Sometimes, however, we do not know names of columns to select in advance. E.g., we have an external variable containing names of columns to select, like this:

-
my_variables <- c("Sepal.Length", "Sepal.Width")
-

We can provide it to select directly:

-
iris %>%
-  select(my_variables)
-
## Note: Using an external vector in selections is ambiguous.
-## i Use `all_of(my_variables)` instead of `my_variables` to silence this message.
-## i See <https://tidyselect.r-lib.org/reference/faq-external-vector.html>.
-## This message is displayed once per session.
-
##   Sepal.Length Sepal.Width
-## 1          5.1         3.5
-## 2          4.9         3.0
-## 3          4.7         3.2
-## 4          4.6         3.1
-## 5          5.0         3.6
-

but it throws a warning. tidyverse boasts detailed messages and it is worth always taking them into consideration. This is not recommended, as it is ambiguous. We can easily imagine situation when there is a column in data called “my_variables”. What should happen, if we have both such a column and such an external variable? Which one would be selected? The answer does not matter for us, as we want to stick to best practices.

-

A solution suggested by authors of dplyr is to use dplyr::all_of(), which explicitly transforms a vector of names (or a single name) into symbols. In this way there is no ambiguity – dplyr knows that it should use columns named by vector my_variables, not use my_variables as a name of column.

-
iris %>%
-  select(all_of(my_variables))
-
##   Sepal.Length Sepal.Width
-## 1          5.1         3.5
-## 2          4.9         3.0
-## 3          4.7         3.2
-## 4          4.6         3.1
-## 5          5.0         3.6
-
-

Problem 2: passing columns as arguments to custom functions

-

This difference between passing a variable name vs or symbol as a name can be especially tricky when building a function which calls dplyr verbs inside of it and is parametrized by column names. Let’s see an example:

-
my_subset <- function(data, my_var) {
-  data %>%
-    select(my_var)
-}
-

This might cause a lot of issues. Should we provide a string as a name (my_subset(iris, "Sepal.Length")) or a symbol (my_subset(iris, Sepal.Length))? To answer this question, we should first be clear about our intent (it would be nice to write a few words of documentation – for other users or for ourselves in the future). Both approaches are possible, but it is better to stick to one.

-

If we decide that we want to use names as a string (it is a common case, e.g. when building shiny app and columns are selected in inputs), then we should use previously shown trick with dplyr::all_of():

-
my_subset_with_strings <- function(data, my_var_as_string) {
-  data %>%
-    select(all_of(my_var_as_string))
-}
-
-my_subset_with_strings(iris, c("Sepal.Length", "Sepal.Width"))
-

If we want to use symbols, just like directly in dplyr functions (mostly when those columns to use are predefined, in our internal functions or analyses), we have to embrace the variable:

-
my_subset_with_symbols <- function(data, my_var_as_symbol) {
-  data %>%
-    select({{ my_var_as_symbol }})
-}
-
-my_subset_with_symbols(iris, Petal.Length)
-
-my_subset_with_symbols(iris, Petal.Length, Sepal.Width)
-
-iris %>%
-  select(Petal.Length)
-
-iris %>%
-  select(Petal.Length, Sepal.Width)
-
-
-my_var_as_symbol = Petal.Length
-iris %>%
-  select(my_var_as_symbol)
-

In this way we let dplyr know that my_var_as_symbol has to be passed directly as user provided it. We can think of embracing as of cut-paste operation. We tell dplyr: “Take what user provided in place of my_var_as_symbol in function call and plug it directly into select, without creating any intermediate variables.”. Call to my_subset_with_symbols() is basically replaced with what lies inside of it. You can see comparison in figure TODO.

-
-
-
-

Problem 3: dynamic columns in purrr formulas in across

-

Solutions above work fine when we provide those column names to dplyr::select(), dplyr::filter() or dplyr::group_by() directly. But sometimes we need a function that does something more. Let’s say we want to have a function do_magic, which takes as an input some data, name of column special and names of other columns others. This function subtracts column special from all columns others.

-

We can try to do it with dplyr::mutate(dplyr::across()). It has a syntax mutate(across(columns_to_mutate, function_to_apply)). If we want to provide a custom unnamed function, we can use purrr formula syntax: ~ expression with .x where .x is column. This (without enclosing it in a function yet) could look like:

-
iris %>%
-  mutate(across(all_of(c("Sepal.Length", "Sepal.Width")), ~ .x - Petal.Length))
-
+--- +title: 'R Basic Advanceds: Variables and Names in dplyr' +author: Dominik Rafacz +date: '2023-01-30' +slug: r-basic-advanceds-variables-and-names-in-dplyr +categories: ['Tutorial'] +tags: ['r', 'tutorial', 'dplyr', 'environments', 'rlang'] +--- + + + +
+

Intro

+

Hello everyone! After an extended hiatus for various reasons (from graduating college to navigating job changes and legal challenges), we’re back and eager to breathe new life into this blog. Given my deep interest in the fundamentals of advanced methods, today we’re delving into an essential topic every dplyr user will eventually face.

+

dplyr is meticulously designed with the primary goal of making code workflows read as naturally and close to plain language as possible. This design philosophy manifests in two critical dimensions: semantic and syntactic.

+

Semantically, the emphasis is on employing words with intuitive and easily understood meanings. For instance, dplyr and its friends adhere to a robust naming convention where function names typically take on verb forms, elucidating the action they perform.

+

Syntactically, the arrangement and combination of these descriptive words is paramount. Arguably, this is even more critical to the user experience. One of the most evident manifestations of this syntactical approach is the tidyverse’s hallmark feature: the pipe operator. But we are not going to tackle this today. I will look into caveats of another essential and intuitive syntactic feature: the use of symbols instead of strings to refer to variables within datasets. This offers a more natural-feeling mode of interaction but, as I have found out over many years of using R, this feature can lead to some problems.

+
+
+

Problem 1: Symbols vs. strings with names

+

Let’s compare how we select columns in a data frame using base R versus dplyr:

+
# base
+iris[, c("Sepal.Length", "Sepal.Width")]
+
+# dplyr
+iris %>%
+  select(Sepal.Length, Sepal.Width)
+

Notice the difference:

+
    +
  • In base R, we use "Sepal.Length", "Sepal.Width", which are strings enclosed in quotes (single and double quotes are both valid).
  • +
  • With dplyr, we have Sepal.Length, Sepal.Width, unquoted symbols.
  • +
+

In the second case symbols are used to access columns in a data frame, just like we use symbols to access any variable or function that we store in our top-level environments. +It is vital to grasp this distinction to sidestep potential pitfalls. which I will discuss in the rest of the post.

+

So, what symbols actually are? We use them as names of objects and this is the identity of their core. This is why it feels natural to use them to not only access top-level variables, but also variables in data. There is more to the nature of symbols, but we will come back to that later.

+

Notice that dplyr is smart enough to let you select variables by strings as well:

+
iris %>%
+  select("Sepal.Length", "Sepal.Width")
+
##   Sepal.Length Sepal.Width
+## 1          5.1         3.5
+## 2          4.9         3.0
+## 3          4.7         3.2
+## 4          4.6         3.1
+## 5          5.0         3.6
+

This is, however, inadvisable, as this is exactly what tidyverse designers wanted to avoid.

+

Now, consider a scenario where we have an external variable storing column names:

+
my_variables <- c("Sepal.Length", "Sepal.Width")
+

Although it might seem intuitive to directly supply it to select:

+
iris %>%
+  select(my_variables)
+
## Warning: Using an external vector in selections was deprecated in tidyselect 1.1.0.
+## ℹ Please use `all_of()` or `any_of()` instead.
+##   # Was:
+##   data %>% select(my_variables)
+## 
+##   # Now:
+##   data %>% select(all_of(my_variables))
+## 
+## See <https://tidyselect.r-lib.org/reference/faq-external-vector.html>.
+## This warning is displayed once every 8 hours.
+## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
+## generated.
+
##   Sepal.Length Sepal.Width
+## 1          5.1         3.5
+## 2          4.9         3.0
+## 3          4.7         3.2
+## 4          4.6         3.1
+## 5          5.0         3.6
+

This generates a warning. Given the tidyverse’s informative error messages, it’s wise to pay heed. Directly supplying can be ambiguous —- imagine having a column named “my_variables”. Which should be selected if we have both the column and the external variable?

+

Diagram showing the dillema that dplyr is faced with when we torment it with ambiguous selections. +To ensure clarity, dplyr authors suggest using dplyr::all_of(), which explicitly converts a name vector into symbols, resolving any ambiguities.

+
iris %>%
+  select(all_of(my_variables))
+
##   Sepal.Length Sepal.Width
+## 1          5.1         3.5
+## 2          4.9         3.0
+## 3          4.7         3.2
+## 4          4.6         3.1
+## 5          5.0         3.6
+
+

Problem 2: Passing column names as arguments to custom functions

+

Differentiating between passing a variable name or a symbol becomes trickier when constructing functions that internally use dplyr verbs. Consider:

+
my_subset <- function(data, my_var) {
+  data %>%
+    select(my_var)
+}
+

This might cause a lot of issues. Should we provide a string as a name (my_subset(iris, "Sepal.Length")) or a symbol (my_subset(iris, Sepal.Length))? To answer this question, we should first be clear about our intent (it would be nice to write a few words of documentation – for other users or for ourselves in the future). Both approaches are possible and valid. It is important to choose one and remain consistent across all functions that we write.

+

For instances where column names are passed as strings (common in Shiny apps when columns are selected by some input), one could utilize the previously discussed dplyr::all_of():

+
my_subset_with_strings <- function(data, my_var_as_string) {
+  data %>%
+    select(all_of(my_var_as_string))
+}
+
+my_subset_with_strings(iris, c("Sepal.Length", "Sepal.Width"))
+

If we want to use symbols, just like directly in dplyr functions (mostly when those columns to use are predefined, in our internal functions or analyses), we have to embrace the variable:

+
my_subset_with_symbols <- function(data, my_var_as_symbol) {
+  data %>%
+    select({{ my_var_as_symbol }})
+}
+
+my_subset_with_symbols(iris, Petal.Length)
+
+my_subset_with_symbols(iris, Petal.Length, Sepal.Width)
+

In this way we let dplyr know that my_var_as_symbol has to be passed directly as user provided it. We can think of embracing as of cut-paste operation. We tell dplyr: “Take what user provided in place of my_var_as_symbol in function call and plug it directly into select, without creating any intermediate variables.”. Call to my_subset_with_symbols() is basically replaced with what lies inside of it.

+
+
+
+

Problem 3: dynamic columns in purrr formulas in across

+

While the above solutions work seamlessly with functions like dplyr::select(), challenges arise when operations grow complex. Suppose we wish to craft a function, do_magic, that takes data, a special column, and several others columns. This function should add the special column to all others.

+

Leveraging dplyr::mutate(dplyr::across()) can achieve this. Its syntax is:

+
mutate(across(columns_to_mutate, function_to_apply))
+

For custom, unnamed functions, the purrr formula syntax (~ expression with .x) is beneficial. In our case (without enclosing it in a function yet) could look like:

+
iris %>%
+  mutate(across(all_of(c("Sepal.Length", "Sepal.Width")), ~ .x - Petal.Length))
+

However, contrary to most languages, in R symbols can be treated as objects themselves. This allows dplyr to even perform such simplifications. The details are irrelevant now

+
diff --git a/content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/selection-ambiguity.png b/content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/selection-ambiguity.png new file mode 100644 index 0000000000000000000000000000000000000000..aafdc5db35306ab8cc1181b272ac016f19479db5 GIT binary patch literal 132392 zcmeFZby(9~A2^JOBFL>00s^8m0@4iv4%p~X(jvVP($b2G3KG)YIoKvKnxP;yI!1?x ztc+1*mWDC~89f;Z2?+&IKOSBW!tGou~iuj?;W4BbdbZZ@6%TxfMJup&;p0uEds(%K}^ne;c&^_V(Y-(kb$T;Ps*!1t6Eq>=QSg6=tp zW|7^|+MvkMx)$f-i176&Yrx=#R$H9-;0O;K2Fo|>R6hAtw48o22+a9~+?gKG`qz@v(JyY&QFk#JmFVLp!)Yz2JJ(&(~CPddP8rqUpeZfz`{aVSo+Ngrh^hW<95StcR23^zk7yNjgo)==gxb6-baViQ@-=BMcBtMED zwOG#|3sHd~`@4T}n;TrtP?jhRY9ylu3c_v(JEsChtk*ovHd8=6rOTMEKH;7BwzWpCuKh0y*p=&fkhWd_A(!A4)H={r$ z@ocwPuV8jMHZlSB53g*On|`+vf#xfT)v(A^U4^Uu3^Sj zkLPk%Q>(5Pe_=#=3n{>^8yhWr9OOB+5Nn0Yq$Cpwz(fd3ac3A~WH>13a~Ld*#N#-4 z2tcPWSWQEg*?fYan3G-z4;Sq%QDEpS=|KhS7TK}RJnopW+a53StvHz}b-=AA%Ja+X zkFVIw|_rmD31@~%%iKlTtC-G`j z!xYD5)nZY_plwE$8q2wRiTV@`i#H@~5!_gX25%bW6X)+OCj2iFb9cS-_eXyY{imO%w z)2%Xag|<`og%_1SA6bLR&csmTCYuDN0|hm&q#fM63-Bd$&yz925ks`{+CI3rHVuYa z?gbrQJ~!Tk2jz>(@4oe_A1cKB`R2+d{S&896LFG|SOZnN!Q+V(S8mFQ+9%iFpeW&1 zY1aqAb+vYL^+y|x8svz4n9=$o$@jmAtm#<4my13n6mr8*m~U51bqiWe=JzdDMmbhB zw+9NbBR%!c z)j^)YVA)E}`trHS&{Dzjt*XuSPM(0LkyN(14iTnBZXlG!$#rUjVb7^=9IhzHj=*q( zdi1<{B8>Cc=UPT~w-|J4_j}k*>x#piz@!Wb$v24)CpZ7A%3ky7vUYSopaw>%CCOM< z9KY1bnpaOp0K7T}vu>mq)3rL5-jnuU3+j=@_Je>M11q~ws&S(oFihm~*M&??pYQTI@=(l!X)7gM?A}A4Tn+TB=~3{!-?qC{Clt z-uZxB_t&D90Y{mn;jv+_mBB-P)6kpZm$GhIlq8A4!nACF6*MOzfQF;CywWnKiC1dX zA11#KzDW|RUMipdE)WmN!|^`?Ow({8fqi>Mv1$1xK*9HrJ`tNda^)V~bmW%v#6opC zzRp2-f%|pYU&T2cSH(<}1skSt`z)uzu$%fH#s6ej!beSNGNOl4_sJ%KmVEHla8nk2 zM0Xa)MmYqUNygevmG|Lxwh?6wHXgH4s6HCyNn-__XIO)DO_i2$8J!eEIE`p8iyBWZ zTmpr zfudC51g|-FGc_hfj7>XxT>AHsM?2tq$e2N1osUF*dXJB}y|)c7=(C>g=3_e!sUGSS z0f$5*@S^nbtuN8S{4kC!@8W3f7^Hggjq>%M*BN02I!$!0Y3V^9E-#PuS%6afO8Azi zD`%Sm4T??aNVoL21?Fm6@w54vv}wq8moG^oT;T6At4Qr>gT?3F0q`j>Y~rB@%=P`7 zx1^~^m)S-UuQ3%08Duu?UzJAGf%Tf{R#ed0%sbo&PnlIo_E{xLta`LEwqHa<@I z-#5!!_RFn5=73K*=%6g30-vVft9FJ#Ofw)0=JviZ>LTk=M+1}vxHsYQ6&AsT!KkbGAa_XA2auc*=6~NQK5= z9(+K53idM5NQxf3`Buck(BEN1Kb^?g`kdd?uMDPhxXspcul1Y=4o2D z#Wlww4+lwWpv9F0pMsK(?LATJm1B^Ew`VMEte6?@>N`%(#^RhMF&=wxPEhxTbOB$R z)^gHL%>41O#fCu}Af9_hts&5zt%(KK%4M`8AMSv+`~?$pYH{dFfym-!`<|wAHs73t z#WY3fa;OHpnSYwLhdnjPCyVlrb{PLd;jb%BO^rrNAMYYXrD*D44CTDtey~8>=?#U37w1acP+OUaAr5KSWymRGQ*#?f!MOFGH`>KTpf2&E;nft>I zOfox1w1G)?M!TU~*R^yHDU3w&p2Tgzjr1XHk-A!tfw~w!wuq#hDYS7p(=3|3F|fKa(_E4IsdWDMM=zgueG~xQgucj><3$fBa+@3`L%42UY zAAO)0RU)D)6~KtB3RsPQFV13_!Hu40H)dM8vfbb6rGBL(w zCh}mQPE>3!Mz#fw-S7FJqc=77L}bqOUT5F_TO#6pK1Kx`)Zx?I=jAxRjxt82Sb$sS z7s~%o8uB)H+I{rO9M#Z2?z7w<iF*v;s1(~!wHBldtk`c~eBnUL^MeHC+H>ndi< zNzWS?XXfY7u#-s>ZMYtNhzd|dm01p7VIhk^4@%@ox4^%!Du!<@xSLPgmLCrHL3jdg zS!w8(+P*HFXK(~owkIl*8*~!-$m}f|BCBT1s2Fn+xcd5?ic(T_-cm79XTS7%ojb&W z6D?Xn;9)IztWniSjzJnwU&YH){RR_)>rFKV5u+hO#%>F;ptKQ z;gQ^)koNfQ@K1RcY$j>f9K|)j&)-GaDsj%Fj~b=fN9QVm>sdOcx$VFIcC&qT*Y`$~cg0=$$0^5SGdCLVMc)lG4O6CC!@}M3x8@4;d*Z))RKDH z<0UF|kQUmsk?ONF-jaXuV$X2w!y|^KIxKeo!O6Rj1~)#YG3Vh)=bZtm6Ys<^SrCW& zOT}P(cftCi>zKhTA6-u70&pLpRJ(1k+`AKnmdm6@`oXdr>XbJ53Dz0q8rI`N9>e3* z+-`D&OLAeMWJ7@CDBYqu8S1f})SP`IN1p>XJ%2H6O*N)v?4sU*-0)E#A67o%x#N?U z8SKj2ZfRmfP#&$l!jR^h~;mH0j)-npl1vZS4q7TxY|{4@{LOLZT9B!u{T&@L9^?Zz^LP@ zBHVoBOF*(BeFc)ct-nGB!50&(Xs?QoT`H7YLX@mtx%$=$EjvmWVZnWn=zih=tcJ1a z`R`@~Y{KA~wbr{MuK<)^eJ6&;ZfE?dvSL#f37qN`OSCU#boP2ZRFw7#m1SOn;clm* z%F1|L_Ts^Wfq-JTjA1E_t`rVY0wFYM7OZvj@JN(DM1u2D3*fK1H?s zX{hQWpJmylrMXS&Rls63RF_9??mDku$9!KZcD5D_R~-6$Zxs4lk|_eVQfMpUrMqw$ zbSa3GOSe^*6&TyP)#Jl8GQ9JYs3%_ikyel4u;mz|OD1YgPrWhw)O^B7wQd@F1j>VH% zPkD7Ez8Ad27mjUYHp}{ka;jE-!JR$G0AJN{AR=^b9x`dSZ=k1 z@8Yl;99~Xs@GImAjL&dcNF^9c2?1)is+1$$CkEGj9#nf*ju}zg1|klo;aV>Ksj}l= zRT-4b@)^btq*XnaZ$;cMk$`p^wPGjf#PTM|h0{k-q-og&3Ch zk+eK=osUt>C)xOWvj!CU z?CB+wCsKJIJ@okk5TkMW^np+O6Z}6uSx=`)UO$- zGOo4LvFqiAgoBp9ttk+B=%>`-)ocH;xn4RIwD*t6iFuBa)f~IX$kf_L>PG#h%~?!8 z(MBF(CLjitG*^sFA?P;gre=~i19zT0#TG;Ra+Kfw3$KmGCrei>*Qq}1L2aC35< zQBfjMpI@@ggHJ~{E6#+b_mB6=Bd)=upqBfEYMDl!P1O5*I2~S>DVaow=19`g?Ey<5JF;H6-SM@F_SqGnyaDros&j5PYw+#IcDS2)4Z~TpcK-IJ^K| zo#xh^8{26~H+AzNo^t;(4AxAb^ujAZNP*y zaV>ulVNaMDdfjiK+Q>Ycnt4TMlP)Vc;s^+Ovt2C}wNHv0{g9tV!|Hf9urt=@*ZR|X zk2Pxg;i(cl$ipLSt;qaI?S&U>iB`wh%`l?DvrJo@aUl$68L;VRNdzPKT~Q|O=7rjO zyq_WA$wR$Y#&%g%hiWQ{zB(RM%}CP9iYTE!Ze3BYsu2*c_6>C%+w)M|3+II_s`{)7 zH>2(>-w1KwRas_YeR_RI8kRiKdfe8EksNUvg-L_x(V4V4AOQ-a z9C)>34p=TK=f?T7orsu9MO1v*rn_ClR+bOZ9(e+&eyihuNDQc{9L>ntK)}rtDrG|lGz2D_r?1tu36tT8zvh!CIjV0xKY1Gg(Ho3PZROBIc1_~G+ zGDtcwjad(~@N+M@o3CNXc7W4?UjtG{wo~xmqm`G!<-1#z@D~2-rVI>$zE7YhGiHAV zG@WW;N0D~vPbliY!e@sF7z{T9?fyR3SAx0}C;0lEWYXavs@r2#0ga17i=U+h&4754 z^b&vs>DbsvUU3(mr_4|Yv7zpza;2HaKFIgG1lAuXolo>RKffzmGF<)64~`G_;MXns z^Cxktq!=@5(IyN*;2TN^vrE$rigGiH0rEBgv6RpQg1R>8He+PY2U@nuTUi8y2~8WZ zDQK9m)4hYNWz61y7z%U9&+s;s7SqLmn zEzE9D=%Dr3xiZ* zK~*h@Ucgb0C~g!kL)hEB!xlmu!Rfw0#uVQ|zzWz|E=xX$#jFXlg*4C|+ zY`EB*BV9JkpE){6L6PbKmtZjgi1#Iag0xNK#0Le@tSGC_@0}rYUh4%s<#Bp#VxggU zu*uk;fR|>+V%j_HpMet6dN=mw3#aEo67O5DMCxwk7AxCu)g>eQh`3plIOnEZxH-B> zAO9db*voa~D_yoxc%!qG+%K(Tyz^jAy2&RLs@|`tTgyWmz0K^|W-*Rzq>u0rK`$vS zGb&cwC!<#0u_g*jd4?!?>HRIO)8T`GHc;<8b(&#;F+-CaZa_Kn=dI_zbD@0~Y;SWt zSRv~YI&kgY7znEod`fH0?0J>3sAFp}I@#UYp$h*ow7-BkZRrA^p3|EH7dZe*qP1fD z{uME`>!#U34}g>Oy4-qc^(DMhRevnZR;i^6kgN*<-qUfQY|={cZNys?h3bWP@*#k& z4)>TbizA|k51sX8WbgvA3#w;Sd_k?xfftn9O?-fk{W@dlbq zb_3frY)3@I7VAHu#f8_dvA&m|1bb=klx+m5v?+OinN(_>SJcFZ_NgFW^)4m z^>7vMRp)@3JKjbpl-89fE3yH_PuhamIQs?LbSPF16JyLl%qnDECGUgZ;ow^T_1g35 z%Eem(KI=njll2INW3nyeg*FBiXFfyJWntg=G2rLuyF%e4eGbyZnMW z&GcM%^HtcxXkj5?J!mK^O=qw8>!o z!7nzGPElpBku#M4#W@RMQqcu1-zSidhI<`hr;GUF(N^Lyo84sf6)eizN!wy;^l9JK zfP0=2RFnQL{kLn;_Ttp{Fg~{L@0nR0hg}S8r~ZDNS71Uvo-Joj#EU!2{}Q{e)7Czk zPQQATBq?=G&j8_wlrEqhU|i6;UuLwoCR6ktY21^Ulq~TjUvCu9tu?==ZInV)m@Tn} z%S^TA{xi~9AQWS0r)L8~(@eb#jq0%(Th11R?}-~1am%C~REDQ$am3cnspj5|8Z_Tw zV~4mmYw%9m#WrugEkNp+0lv@#9wPerREMH=@#I>dsPrHX4XklIjopCnLHP^KFxZ5A z?;5TgdSbCU7Wj-`g%~8VsIi@Y6;}JznY0BtfSv%a;_M7PR-OA}ZysgqemL$c@&7!w zzbzI;C6ZGsH!DOd{a6be>y|m66Aofr?!+<7gw(P>h0dq0n*FyHVA{370(S7Fi)asz zldhYZUK}2ns5H9T)MT<#Lo@SsYM*yBxcu? zGw&J}$|k@Tm`r(#dK7YGv{4RAG~UsvM7-VUF7)ZSQJ;R%7hg!szP+~jM=<%wu9ceD zwnY+pc9yHRTH06CA4YA38Y2xpOQ^A2O3JzziFuahCaQEN&mQ~JSh$DQqWIf2)19(wrUvHOzuuB= zwGV-<=M9!KT046_Y%>pCI-rD}I!?b@Z*9mk>$z9HCIJAuyX#QF+&DJEx+8GvT6#?J zpGy4>zCy`K5o~>{&p|k^YZX(gTG$$0s&K0bobJ*iqd*g04UaX6=6Y|Ry0KMNBTFpi zeGk{_$Ajz95Au7kjKj@Dx?tIG9{SY3pU;f*N|u}r+tOmAk=gqL8Krj$W(i4@FfP0O zi(2-F`LQ}*EirJFLi92Gv}~PS%Nu7&S&pbB+diDC_YB2z7(%nm(DRABV+reCae5Y& zhhi4J3Ve(3HR%YXet425P2rxZhdWsz=E6h_0$nudZ>A}sk;wKo1z zl$!3*K|qf>KUFTGOYqNTfozUySfbVwBqMC&EsdmIGIo%J9tYl@^7dbSsO~}jXFKZE zO6`n^LFgCxaeju}ic$8j4R@L;IK}5ge?Z~Nq~R+31K-zDlUK&-bb4;m7ua(6MjtNa`!b<5 z#M0E`pD|ah(+YX?Bp~Q&tFjdOC8Cn(1y$nPsoC}3hlHyT?eC7Sci8~NL(3O|tz}lc z2|RA^d~;2uM8{1dEMp#jpB57lU9ic$8r zB70Y!3@ZTMc~7HpPLJ;o5)>~|W4~(U!=g=%EI6*~ zzf(?tEnC@kzm?I-q!s0(jv?ewRx##12MD`=l`gEy!YA<^IlPB9>UyndeCRJ-4J!f_ zV_Yj0Q=)RJE=-yl<2nu0qowfnN1R2OzL01xe5)Be!PB@fj%Q)Bg=rwKaFY;fc8@i- zcx)RuTg?zKE+cz0Dz0N{BuXc*_r3=%e|CQ+tTqn9Y?>W zwWw?$o}a+at8G>fO%6Enkl#GIYTkQSrBGzhW($r6c^j@l%`i5+yp9v1_aB2hY^U?y zuisKvNT1@w?CYwAOEGhVtAl?%2XYU{bxas<8N7VHSs&!#qId}_spn}EUQ%}WJRv|3 zo1Hx04w{QCuW=vyUAN4{!tQhO) zo1|qbTD)HM487Vp+mCAGU>8xlvbO7L{k{o(1-=?!B;6B;w?*t{8Jlp?ip*iV6FxEq#R8CRJcP*1TFM#ngB^GrDy`ls#q$5@+L>&rC9V;jGkCp{7qwLi& zwMmtg#R4f~98WfXIY-Xr>j>|cf6J!@m7*MwLf;r9AL&yzlRJ3DyMgR7lwP4`?uUiS zHdxqCZ~HOAoGmw*UJNGu41OG4(u(MjEHR$0a(T<}7QEfG|9iZfp;j-|y)*kk)9-FE z`VS35-D$30>@=U%*?e}F;oE;UPR3ejGPH`|EaZ}3zvE-{L(s%!U~=bivS5W2t6oP9 zmYPk3jgzZ8+4l=D@0iioI=jMhJY8o$N%CGEe6?}b!r^2j8(L*}N6E`;_*o!8GsNjx zsecU10bM|kxFz*8XLe)#Um0B5oi0R&>m?t{|LWSrIbL~Y53K9Lrv{Z;;gYpO`~kr6 zy1QbF3K5aZa@#x&aQqjnKHQJ3D^%N9fYqdlA&Osrjy7#Zoc5-kN|S=r?4X3z-mKAF z`i!avtPyTh*CQeC|MXe$eAtExfPyKDbH|()qOokZ`OTzVd#;*!hf=zJz|b+#Ghho5 zbrJ{HV=4=a2>+AYm1dqn(6p}}NayGP zCU9U}1Y7HVP7bUQ276V>~f`>?u66GKu3uT`O(Z? z*g|T(!UxH6FP;ZoNvqvghvT_DcI-J`Qc`CnTrR_vDAGx-sON=>sfP@|V;Zp-+hnro zX!|nzDqPT0JiZ<&p~AwHTCll^w%`145nF4pIJYHKw3G6aHY>8X1pt*Y?O>WfS$>tgh$HKX^&hB>J%@Kmt}EOn|Ee<1cDr^q0drT zl(oHY@R&S!5%V(B_d5c0GQJ_Mq#dq5)$oKT`QDA%dyeFj)}Q_0Afk$9O;jNCVzs*@ zG4Ji`q+aP5XXuTl=@g{vI%%LiYvS_AZ$N9D9n>T+g; z^G7{>-!U{N>xCG!0nhP)zv)3EAAeA$daEcJg`+)5&Ez*C-xzA=#0*IBh%VJ|$PFXH z-&rb?4_WP)6S!~U_J~I4BUXQd;$MQ!{Gdz_lTg)6S?5G$SxK@pC9R-+(!>$%YObvpuZ zx!y)u56@g)f2|_Qs`P99>XjT^i(9|5Sqn#||I^{AO-}v&Ul3 z+qRc4PVPX$@4-!I?$zoLChAUlHOtrmC1adVLgLKdPwk@ND33hXS?G$+V<#Z=4yNU9GtMYAS)48s;; zCqVI!TZ2gn>46m@vVHt2eRpQ5WuFl9JO`D=vF3QSmzRl8TtCo<`oF;ulsgC4XuI^v zD+|Be4yECH#*!@c*RMUJC>WV*jN7+NNKm#b;mhM|F`!`!)aK5P0Jdkd+siw= zyVzZt8*Fi)vMCsqv5!rUvM}PfXsc4&`ayOeoBC?u;EBPr}_ZI{70V@$<#N zK?X7GA~EC_JFEhZj0y}u6(jR8qh$j*Z4AuAvkjk}*cR;!T8d~S)`D*u%5}P|F7Uhk z!qQLm%7{F5sqEI>BH@S1Iyz_uqubS@yF4f;(i4go=XaKG%zCtT^+8fSjA!OPU{LI5g!|y8(o&9#mCja;@B-$_A zMnT9IWKiwv72MFuNeMKL(A8js$Q}MrF8m_d0XbdxeyzF*rat}QzzrVm`!sOR(RXGR zGHMp6+u+OJuuebuTS{Sb^T(b~UxQ(8e!dsy#qphIy4NZ`)m66tL!S7DW* zRsMFPhjeU2X)@_we?V@W7e^&|i9K6c!%;?8Vwa3JgnuBYC-p*iUFm~4@4U@@^1&>+ zd{Q7=yZfGqk>`r4zt<>Lm|PRxYO?rgl%-qJJs^h0d;m<$jReIe+$%y74Gt&0}AJY)|ajIJc+R0(&b zgq3@a_r9WEzSl0oaH9%~OPgi>F0`TR%gn&`Lho#CeCl!EnZE;Pz5(QxDE6pE)!2Tf z<@G)w)}j99G!&Jry=uF*ryCd8kc<84-*f9f6(6hy#Cup8+ht;4jm^opZop$S#6IkM zQn)^KdWHN?#bnk$-`kPpQvI}9;>13%*f0?_w%5HF{6tce9c z%Jx^(#e^t64NrzLYbz8e%2$tXZ8#|k-YaE7Y{PgQey4W0do`f;Cshr(otIuonFIRd z0?i^) z$}i&?v#QeNV7|9|q*Y*tT}CTJM^^JS6X?DQv7zH7--Cbb-^zFFi(gJc;~d>!Lyi*< zaPqbsV8RWsm3x#;ceUa5TitEIS2;PC94Y4Kk&EW=eue>|n3{PR>k+a!ar{cw60vqS zUZdX7t5ZcQN6J>f2661{U9Nw!&gQsPYb3zfX}%kgP?�&yUNaf*;&hu6Qu)8%Zps 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

b0tADEB#89K&hjoX}iw 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 + + +presentpresentpresentambiguity!presentnot presentnot present+ warning From f2f7ca0d6caf37faf2339fb5078183f8a79ff0d8 Mon Sep 17 00:00:00 2001 From: DominikRafacz Date: Tue, 5 Sep 2023 20:29:13 +0200 Subject: [PATCH 3/9] finish article --- .../index.Rmd | 52 ++++++++++++++++++- .../index.html | 50 +++++++++++++++++- 2 files changed, 100 insertions(+), 2 deletions(-) diff --git a/content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/index.Rmd b/content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/index.Rmd index c39711f..f413092 100644 --- a/content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/index.Rmd +++ b/content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/index.Rmd @@ -136,4 +136,54 @@ iris %>% mutate(across(all_of(c("Sepal.Length", "Sepal.Width")), ~ .x - Petal.Length)) ``` -However, contrary to most languages, in R **symbols can be treated as objects themselves**. This allows dplyr to even perform such simplifications. The details are irrelevant now +Elegant, isn't it? Now, let's proceed by encapsulating this logic within a function where column names are passed as strings: + +```{r} +do_magic <- function(data, special, others) { + data %>% + mutate(across(all_of(others), ~ .x - all_of(special))) +} + +# won't work: +# do_magic(iris, special = "Petal.Length", others = c("Sepal.Length", "Sepal.Width")) +``` + +Surprisingly, it fails! When used within the context of `across`, dplyr seems unable to utilize the tidyselect rules (the ones that make `all_of()` possible). But we're not defeated; let's try embracing: + +```{r} +do_magic_but_better <- function(data, special, others) { + data %>% + mutate(across(all_of(others), ~ .x - {{special}})) +} + +do_magic_but_better(iris, special = Petal.Length, others = c("Sepal.Length", "Sepal.Width")) +``` + +By adopting this approach, it's imperative to provide special as a symbol. Also, this does not look fine: one parameter is provided as symbol, another one is as character vector... **We should always aim at being consistent**. Either all column-like parameters should be symbols or all should be character strings. There are pros and cons to both ways. Let's say that we want to stick to strings only. How can we do it? + +#### Tip: when `all_of()` does not work, use `.data` + +There's a workaround for this conundrum: + +```{r} +do_magic_but_in_other_way <- function(data, special, others) { + data %>% + mutate(across(all_of(others), ~ .x - .data[[special]])) +} + +do_magic_but_in_other_way(iris, special = "Petal.Length", others = c("Sepal.Length", "Sepal.Width")) +``` + +When you need to reference the underlying data within the context of functions, the `.data` pronoun comes to the rescue. As demonstrated, it operates similarly to directly accessing the data. + +## Summary & Next Steps + +Throughout this post, we ventured deep into some of the intricacies of dplyr. We've unraveled how the package strives to make our code both semantic and syntactic, all while simplifying complex operations. The power of symbols and the utility of functions like `all_of()` and `.data` demonstrate just how dynamic and adaptable dplyr can be, especially when working with variable column names. While we've covered much ground, the world of dplyr is vast and constantly evolving. We are aware that all this *embracing* and *tidyselect* rules might be intimidating, but we will be continue to explore more facets of the tidyverse in future posts of "basic advanceds", aiming to empower you with advanced techniques that enhance your data analysis journey. + +If you've found this post enlightening and wish to delve deeper, or if you have any questions or insights, we'd love to hear from you! You can contact us directly via [X](https://twitter.com/Rturtletopia). Alternatively, for those who prefer a more open-source avenue, feel free to open an issue on our [GitHub](https://github.com/turtletopia/turtletopia.github.io/issues) repository. Your feedback and insights not only help us improve, but they also contribute to the broader data science community. + +Until next time, keep exploring, learning, and sharing! + +## Dive Deeper: Resources for the Curious Minds: + +For those wishing to delve further or who may have lingering questions: [Dplyr official programming guide](https://dplyr.tidyverse.org/articles/programming.html) diff --git a/content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/index.html b/content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/index.html index 6835e05..c186445 100644 --- a/content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/index.html +++ b/content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/index.html @@ -112,5 +112,53 @@

Problem 3: dynamic columns in purrr formulas in across

For custom, unnamed functions, the purrr formula syntax (~ expression with .x) is beneficial. In our case (without enclosing it in a function yet) could look like:

iris %>%
   mutate(across(all_of(c("Sepal.Length", "Sepal.Width")), ~ .x - Petal.Length))
-

However, contrary to most languages, in R symbols can be treated as objects themselves. This allows dplyr to even perform such simplifications. The details are irrelevant now

+

Elegant, isn’t it? Now, let’s proceed by encapsulating this logic within a function where column names are passed as strings:

+
do_magic <- function(data, special, others) {
+  data %>%
+    mutate(across(all_of(others), ~ .x - all_of(special)))
+}
+
+# won't work:
+# do_magic(iris, special = "Petal.Length", others = c("Sepal.Length", "Sepal.Width"))
+

Surprisingly, it fails! When used within the context of across, dplyr seems unable to utilize the tidyselect rules (the ones that make all_of() possible). But we’re not defeated; let’s try embracing:

+
do_magic_but_better <- function(data, special, others) {
+  data %>%
+    mutate(across(all_of(others), ~ .x - {{special}}))
+}
+
+do_magic_but_better(iris, special = Petal.Length, others = c("Sepal.Length", "Sepal.Width"))
+
##   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
+## 1          3.7         2.1          1.4         0.2  setosa
+## 2          3.5         1.6          1.4         0.2  setosa
+## 3          3.4         1.9          1.3         0.2  setosa
+## 4          3.1         1.6          1.5         0.2  setosa
+## 5          3.6         2.2          1.4         0.2  setosa
+

By adopting this approach, it’s imperative to provide special as a symbol. Also, this does not look fine: one parameter is provided as symbol, another one is as character vector… We should always aim at being consistent. Either all column-like parameters should be symbols or all should be character strings. There are pros and cons to both ways. Let’s say that we want to stick to strings only. How can we do it?

+
+

Tip: when all_of() does not work, use .data

+

There’s a workaround for this conundrum:

+
do_magic_but_in_other_way <- function(data, special, others) {
+  data %>%
+    mutate(across(all_of(others), ~ .x - .data[[special]]))
+}
+
+do_magic_but_in_other_way(iris, special = "Petal.Length", others = c("Sepal.Length", "Sepal.Width"))
+
##   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
+## 1          3.7         2.1          1.4         0.2  setosa
+## 2          3.5         1.6          1.4         0.2  setosa
+## 3          3.4         1.9          1.3         0.2  setosa
+## 4          3.1         1.6          1.5         0.2  setosa
+## 5          3.6         2.2          1.4         0.2  setosa
+

When you need to reference the underlying data within the context of functions, the .data pronoun comes to the rescue. As demonstrated, it operates similarly to directly accessing the data.

+
+
+

Summary & Next Steps

+

Throughout this post, we ventured deep into some of the intricacies of dplyr. We’ve unraveled how the package strives to make our code both semantic and syntactic, all while simplifying complex operations. The power of symbols and the utility of functions like all_of() and .data demonstrate just how dynamic and adaptable dplyr can be, especially when working with variable column names. While we’ve covered much ground, the world of dplyr is vast and constantly evolving. We are aware that all this embracing and tidyselect rules might be intimidating, but we will be continue to explore more facets of the tidyverse in future posts of “basic advanceds”, aiming to empower you with advanced techniques that enhance your data analysis journey.

+

If you’ve found this post enlightening and wish to delve deeper, or if you have any questions or insights, we’d love to hear from you! You can contact us directly via X. Alternatively, for those who prefer a more open-source avenue, feel free to open an issue on our GitHub repository. Your feedback and insights not only help us improve, but they also contribute to the broader data science community.

+

Until next time, keep exploring, learning, and sharing!

+
+
+

Dive Deeper: Resources for the Curious Minds:

+

For those wishing to delve further or who may have lingering questions: Dplyr official programming guide

+
From 2864e3495c2013a1df2ccd4b6e30b616e87ffa0d Mon Sep 17 00:00:00 2001 From: Laura Date: Thu, 7 Sep 2023 20:53:34 +0200 Subject: [PATCH 4/9] fix image path --- .../{ => images}/selection-ambiguity.png | Bin .../{ => images}/selection-ambiguity.svg | 0 .../index.Rmd | 378 +++++++++--------- .../index.html | 7 +- 4 files changed, 191 insertions(+), 194 deletions(-) rename content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/{ => images}/selection-ambiguity.png (100%) rename content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/{ => images}/selection-ambiguity.svg (100%) diff --git a/content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/selection-ambiguity.png b/content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/images/selection-ambiguity.png similarity index 100% rename from content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/selection-ambiguity.png rename to content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/images/selection-ambiguity.png diff --git a/content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/selection-ambiguity.svg b/content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/images/selection-ambiguity.svg similarity index 100% rename from content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/selection-ambiguity.svg rename to content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/images/selection-ambiguity.svg diff --git a/content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/index.Rmd b/content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/index.Rmd index f413092..d77cc80 100644 --- a/content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/index.Rmd +++ b/content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/index.Rmd @@ -1,189 +1,189 @@ ---- -title: 'R Basic Advanceds: Variables and Names in dplyr' -author: Dominik Rafacz -date: '2023-01-30' -slug: r-basic-advanceds-variables-and-names-in-dplyr -categories: ['Tutorial'] -tags: ['r', 'tutorial', 'dplyr', 'environments', 'rlang'] ---- - -# Intro - -Hello everyone! After an extended hiatus for various reasons (from graduating college to navigating job changes and legal challenges), we're back and eager to breathe new life into this blog. Given my deep interest in the fundamentals of advanced methods, today we're delving into an essential topic every dplyr user will eventually face. - -dplyr is meticulously designed with the primary goal of making code workflows read as naturally and close to plain language as possible. This design philosophy manifests in two critical dimensions: *semantic* and *syntactic*. - -Semantically, the emphasis is on **employing words with intuitive and easily understood meanings**. For instance, dplyr and its friends adhere to a robust naming convention where function names typically take on verb forms, elucidating the action they perform. - -Syntactically, the **arrangement and combination of these descriptive words is paramount**. Arguably, this is even more critical to the user experience. One of the most evident manifestations of this syntactical approach is the tidyverse's hallmark feature: **the pipe operator**. But we are not going to tackle this today. I will look into caveats of another essential and intuitive syntactic feature: the **use of symbols instead of strings to refer to variables within datasets**. This offers a more natural-feeling mode of interaction but, as I have found out over many years of using R, this feature can lead to some problems. - - -```{r message=FALSE, warning=FALSE, include=FALSE} -library(dplyr) -iris <- iris %>% slice(1:5) -``` - -# Problem 1: Symbols vs. strings with names - -Let's compare how we select columns in a data frame using base R versus dplyr: - -```{r eval=FALSE} -# base -iris[, c("Sepal.Length", "Sepal.Width")] - -# dplyr -iris %>% - select(Sepal.Length, Sepal.Width) -``` - -Notice the difference: - -* In base R, we use `"Sepal.Length", "Sepal.Width"`, which are **strings** enclosed in quotes (single and double quotes are both valid). -* With dplyr, we have `Sepal.Length, Sepal.Width`, unquoted **symbols**. - -In the second case *symbols* are used to access columns in a data frame, just like we use symbols to access any variable or function that we store in our top-level environments. -It is vital to grasp this distinction to sidestep potential pitfalls. which I will discuss in the rest of the post. - -So, what symbols actually are? We use them as names of objects and this is the identity of their core. This is why it feels natural to use them to not only access top-level variables, but also variables in data. There is more to the nature of symbols, but we will come back to that later. - -Notice that dplyr is smart enough to let you select variables by strings as well: - -```{r} -iris %>% - select("Sepal.Length", "Sepal.Width") -``` - -This is, however, inadvisable, as this is exactly what tidyverse designers wanted to avoid. - -Now, consider a scenario where we have an external variable storing column names: - -```{r} -my_variables <- c("Sepal.Length", "Sepal.Width") -``` - -Although it might seem intuitive to directly supply it to select: - -```{r warning=TRUE} -iris %>% - select(my_variables) -``` - -This generates a warning. Given the tidyverse's informative error messages, it's wise to pay heed. Directly supplying can be ambiguous —- imagine having a column named "my_variables". Which should be selected if we have both the column and the external variable? - - -![Diagram showing the dillema that dplyr is faced with when we torment it with ambiguous selections.](/images/selection-ambiguity.png) -To ensure clarity, dplyr authors suggest using dplyr::all_of(), which explicitly converts a name vector into symbols, resolving any ambiguities. - -```{r warning=TRUE} -iris %>% - select(all_of(my_variables)) -``` - -## Problem 2: Passing column names as arguments to custom functions - -Differentiating between passing a variable name or a symbol becomes trickier when constructing functions that internally use dplyr verbs. Consider: - -```{r} -my_subset <- function(data, my_var) { - data %>% - select(my_var) -} -``` - -This might cause a lot of issues. Should we provide a string as a name (`my_subset(iris, "Sepal.Length")`) or a symbol (`my_subset(iris, Sepal.Length)`)? To answer this question, **we should first be clear about our intent** (it would be nice to write a few words of documentation -- for other users or for ourselves in the future). **Both approaches are possible and valid**. It is important to **choose one and remain consistent** across all functions that we write. - -For instances where column names are passed as strings (common in Shiny apps when columns are selected by some input), one could utilize the previously discussed `dplyr::all_of()`: - - -```{r, eval=FALSE} -my_subset_with_strings <- function(data, my_var_as_string) { - data %>% - select(all_of(my_var_as_string)) -} - -my_subset_with_strings(iris, c("Sepal.Length", "Sepal.Width")) -``` - -If we want to use symbols, just like directly in dplyr functions (mostly when those columns to use are predefined, in our internal functions or analyses), we have to *embrace* the variable: - -```{r, eval=FALSE} -my_subset_with_symbols <- function(data, my_var_as_symbol) { - data %>% - select({{ my_var_as_symbol }}) -} - -my_subset_with_symbols(iris, Petal.Length) - -my_subset_with_symbols(iris, Petal.Length, Sepal.Width) -``` - -In this way we let dplyr know that `my_var_as_symbol` has to be passed directly as user provided it. We can think of embracing as of cut-paste operation. We tell dplyr: "Take what user provided in place of `my_var_as_symbol` in function call and plug it directly into `select`, without creating any intermediate variables.". Call to `my_subset_with_symbols()` is basically replaced with what lies inside of it. - -# Problem 3: dynamic columns in purrr formulas in `across` - -While the above solutions work seamlessly with functions like `dplyr::select()`, challenges arise when operations grow complex. Suppose we wish to craft a function, `do_magic`, that takes data, a special `column`, and several `others` columns. This function should add the special column to all others. - -Leveraging `dplyr::mutate(dplyr::across())` can achieve this. Its syntax is: - -```{r eval=FALSE} -mutate(across(columns_to_mutate, function_to_apply)) -``` - -For custom, unnamed functions, the *purrr formula syntax* (`~ expression` with `.x`) is beneficial. In our case (without enclosing it in a function yet) could look like: - -```{r, eval=FALSE} -iris %>% - mutate(across(all_of(c("Sepal.Length", "Sepal.Width")), ~ .x - Petal.Length)) -``` - -Elegant, isn't it? Now, let's proceed by encapsulating this logic within a function where column names are passed as strings: - -```{r} -do_magic <- function(data, special, others) { - data %>% - mutate(across(all_of(others), ~ .x - all_of(special))) -} - -# won't work: -# do_magic(iris, special = "Petal.Length", others = c("Sepal.Length", "Sepal.Width")) -``` - -Surprisingly, it fails! When used within the context of `across`, dplyr seems unable to utilize the tidyselect rules (the ones that make `all_of()` possible). But we're not defeated; let's try embracing: - -```{r} -do_magic_but_better <- function(data, special, others) { - data %>% - mutate(across(all_of(others), ~ .x - {{special}})) -} - -do_magic_but_better(iris, special = Petal.Length, others = c("Sepal.Length", "Sepal.Width")) -``` - -By adopting this approach, it's imperative to provide special as a symbol. Also, this does not look fine: one parameter is provided as symbol, another one is as character vector... **We should always aim at being consistent**. Either all column-like parameters should be symbols or all should be character strings. There are pros and cons to both ways. Let's say that we want to stick to strings only. How can we do it? - -#### Tip: when `all_of()` does not work, use `.data` - -There's a workaround for this conundrum: - -```{r} -do_magic_but_in_other_way <- function(data, special, others) { - data %>% - mutate(across(all_of(others), ~ .x - .data[[special]])) -} - -do_magic_but_in_other_way(iris, special = "Petal.Length", others = c("Sepal.Length", "Sepal.Width")) -``` - -When you need to reference the underlying data within the context of functions, the `.data` pronoun comes to the rescue. As demonstrated, it operates similarly to directly accessing the data. - -## Summary & Next Steps - -Throughout this post, we ventured deep into some of the intricacies of dplyr. We've unraveled how the package strives to make our code both semantic and syntactic, all while simplifying complex operations. The power of symbols and the utility of functions like `all_of()` and `.data` demonstrate just how dynamic and adaptable dplyr can be, especially when working with variable column names. While we've covered much ground, the world of dplyr is vast and constantly evolving. We are aware that all this *embracing* and *tidyselect* rules might be intimidating, but we will be continue to explore more facets of the tidyverse in future posts of "basic advanceds", aiming to empower you with advanced techniques that enhance your data analysis journey. - -If you've found this post enlightening and wish to delve deeper, or if you have any questions or insights, we'd love to hear from you! You can contact us directly via [X](https://twitter.com/Rturtletopia). Alternatively, for those who prefer a more open-source avenue, feel free to open an issue on our [GitHub](https://github.com/turtletopia/turtletopia.github.io/issues) repository. Your feedback and insights not only help us improve, but they also contribute to the broader data science community. - -Until next time, keep exploring, learning, and sharing! - -## Dive Deeper: Resources for the Curious Minds: - -For those wishing to delve further or who may have lingering questions: [Dplyr official programming guide](https://dplyr.tidyverse.org/articles/programming.html) +--- +title: 'R Basic Advanceds: Variables and Names in dplyr' +author: Dominik Rafacz +date: '2023-01-30' +slug: r-basic-advanceds-variables-and-names-in-dplyr +categories: ['Tutorial'] +tags: ['r', 'tutorial', 'dplyr', 'environments', 'rlang'] +--- + +# Intro + +Hello everyone! After an extended hiatus for various reasons (from graduating college to navigating job changes and legal challenges), we're back and eager to breathe new life into this blog. Given my deep interest in the fundamentals of advanced methods, today we're delving into an essential topic every dplyr user will eventually face. + +dplyr is meticulously designed with the primary goal of making code workflows read as naturally and close to plain language as possible. This design philosophy manifests in two critical dimensions: *semantic* and *syntactic*. + +Semantically, the emphasis is on **employing words with intuitive and easily understood meanings**. For instance, dplyr and its friends adhere to a robust naming convention where function names typically take on verb forms, elucidating the action they perform. + +Syntactically, the **arrangement and combination of these descriptive words is paramount**. Arguably, this is even more critical to the user experience. One of the most evident manifestations of this syntactical approach is the tidyverse's hallmark feature: **the pipe operator**. But we are not going to tackle this today. I will look into caveats of another essential and intuitive syntactic feature: the **use of symbols instead of strings to refer to variables within datasets**. This offers a more natural-feeling mode of interaction but, as I have found out over many years of using R, this feature can lead to some problems. + + +```{r message=FALSE, warning=FALSE, include=FALSE} +library(dplyr) +iris <- iris %>% slice(1:5) +``` + +# Problem 1: Symbols vs. strings with names + +Let's compare how we select columns in a data frame using base R versus dplyr: + +```{r eval=FALSE} +# base +iris[, c("Sepal.Length", "Sepal.Width")] + +# dplyr +iris %>% + select(Sepal.Length, Sepal.Width) +``` + +Notice the difference: + +* In base R, we use `"Sepal.Length", "Sepal.Width"`, which are **strings** enclosed in quotes (single and double quotes are both valid). +* With dplyr, we have `Sepal.Length, Sepal.Width`, unquoted **symbols**. + +In the second case *symbols* are used to access columns in a data frame, just like we use symbols to access any variable or function that we store in our top-level environments. +It is vital to grasp this distinction to sidestep potential pitfalls. which I will discuss in the rest of the post. + +So, what symbols actually are? We use them as names of objects and this is the identity of their core. This is why it feels natural to use them to not only access top-level variables, but also variables in data. There is more to the nature of symbols, but we will come back to that later. + +Notice that dplyr is smart enough to let you select variables by strings as well: + +```{r} +iris %>% + select("Sepal.Length", "Sepal.Width") +``` + +This is, however, inadvisable, as this is exactly what tidyverse designers wanted to avoid. + +Now, consider a scenario where we have an external variable storing column names: + +```{r} +my_variables <- c("Sepal.Length", "Sepal.Width") +``` + +Although it might seem intuitive to directly supply it to select: + +```{r warning=TRUE} +iris %>% + select(my_variables) +``` + +This generates a warning. Given the tidyverse's informative error messages, it's wise to pay heed. Directly supplying can be ambiguous —- imagine having a column named "my_variables". Which should be selected if we have both the column and the external variable? + + +![Diagram showing the dillema that dplyr is faced with when we torment it with ambiguous selections.](images/selection-ambiguity.png) +To ensure clarity, dplyr authors suggest using dplyr::all_of(), which explicitly converts a name vector into symbols, resolving any ambiguities. + +```{r warning=TRUE} +iris %>% + select(all_of(my_variables)) +``` + +## Problem 2: Passing column names as arguments to custom functions + +Differentiating between passing a variable name or a symbol becomes trickier when constructing functions that internally use dplyr verbs. Consider: + +```{r} +my_subset <- function(data, my_var) { + data %>% + select(my_var) +} +``` + +This might cause a lot of issues. Should we provide a string as a name (`my_subset(iris, "Sepal.Length")`) or a symbol (`my_subset(iris, Sepal.Length)`)? To answer this question, **we should first be clear about our intent** (it would be nice to write a few words of documentation -- for other users or for ourselves in the future). **Both approaches are possible and valid**. It is important to **choose one and remain consistent** across all functions that we write. + +For instances where column names are passed as strings (common in Shiny apps when columns are selected by some input), one could utilize the previously discussed `dplyr::all_of()`: + + +```{r, eval=FALSE} +my_subset_with_strings <- function(data, my_var_as_string) { + data %>% + select(all_of(my_var_as_string)) +} + +my_subset_with_strings(iris, c("Sepal.Length", "Sepal.Width")) +``` + +If we want to use symbols, just like directly in dplyr functions (mostly when those columns to use are predefined, in our internal functions or analyses), we have to *embrace* the variable: + +```{r, eval=FALSE} +my_subset_with_symbols <- function(data, my_var_as_symbol) { + data %>% + select({{ my_var_as_symbol }}) +} + +my_subset_with_symbols(iris, Petal.Length) + +my_subset_with_symbols(iris, Petal.Length, Sepal.Width) +``` + +In this way we let dplyr know that `my_var_as_symbol` has to be passed directly as user provided it. We can think of embracing as of cut-paste operation. We tell dplyr: "Take what user provided in place of `my_var_as_symbol` in function call and plug it directly into `select`, without creating any intermediate variables.". Call to `my_subset_with_symbols()` is basically replaced with what lies inside of it. + +# Problem 3: dynamic columns in purrr formulas in `across` + +While the above solutions work seamlessly with functions like `dplyr::select()`, challenges arise when operations grow complex. Suppose we wish to craft a function, `do_magic`, that takes data, a special `column`, and several `others` columns. This function should add the special column to all others. + +Leveraging `dplyr::mutate(dplyr::across())` can achieve this. Its syntax is: + +```{r eval=FALSE} +mutate(across(columns_to_mutate, function_to_apply)) +``` + +For custom, unnamed functions, the *purrr formula syntax* (`~ expression` with `.x`) is beneficial. In our case (without enclosing it in a function yet) could look like: + +```{r, eval=FALSE} +iris %>% + mutate(across(all_of(c("Sepal.Length", "Sepal.Width")), ~ .x - Petal.Length)) +``` + +Elegant, isn't it? Now, let's proceed by encapsulating this logic within a function where column names are passed as strings: + +```{r} +do_magic <- function(data, special, others) { + data %>% + mutate(across(all_of(others), ~ .x - all_of(special))) +} + +# won't work: +# do_magic(iris, special = "Petal.Length", others = c("Sepal.Length", "Sepal.Width")) +``` + +Surprisingly, it fails! When used within the context of `across`, dplyr seems unable to utilize the tidyselect rules (the ones that make `all_of()` possible). But we're not defeated; let's try embracing: + +```{r} +do_magic_but_better <- function(data, special, others) { + data %>% + mutate(across(all_of(others), ~ .x - {{special}})) +} + +do_magic_but_better(iris, special = Petal.Length, others = c("Sepal.Length", "Sepal.Width")) +``` + +By adopting this approach, it's imperative to provide special as a symbol. Also, this does not look fine: one parameter is provided as symbol, another one is as character vector... **We should always aim at being consistent**. Either all column-like parameters should be symbols or all should be character strings. There are pros and cons to both ways. Let's say that we want to stick to strings only. How can we do it? + +#### Tip: when `all_of()` does not work, use `.data` + +There's a workaround for this conundrum: + +```{r} +do_magic_but_in_other_way <- function(data, special, others) { + data %>% + mutate(across(all_of(others), ~ .x - .data[[special]])) +} + +do_magic_but_in_other_way(iris, special = "Petal.Length", others = c("Sepal.Length", "Sepal.Width")) +``` + +When you need to reference the underlying data within the context of functions, the `.data` pronoun comes to the rescue. As demonstrated, it operates similarly to directly accessing the data. + +## Summary & Next Steps + +Throughout this post, we ventured deep into some of the intricacies of dplyr. We've unraveled how the package strives to make our code both semantic and syntactic, all while simplifying complex operations. The power of symbols and the utility of functions like `all_of()` and `.data` demonstrate just how dynamic and adaptable dplyr can be, especially when working with variable column names. While we've covered much ground, the world of dplyr is vast and constantly evolving. We are aware that all this *embracing* and *tidyselect* rules might be intimidating, but we will be continue to explore more facets of the tidyverse in future posts of "basic advanceds", aiming to empower you with advanced techniques that enhance your data analysis journey. + +If you've found this post enlightening and wish to delve deeper, or if you have any questions or insights, we'd love to hear from you! You can contact us directly via [X](https://twitter.com/Rturtletopia). Alternatively, for those who prefer a more open-source avenue, feel free to open an issue on our [GitHub](https://github.com/turtletopia/turtletopia.github.io/issues) repository. Your feedback and insights not only help us improve, but they also contribute to the broader data science community. + +Until next time, keep exploring, learning, and sharing! + +## Dive Deeper: Resources for the Curious Minds: + +For those wishing to delve further or who may have lingering questions: [Dplyr official programming guide](https://dplyr.tidyverse.org/articles/programming.html) diff --git a/content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/index.html b/content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/index.html index c186445..3a9edab 100644 --- a/content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/index.html +++ b/content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/index.html @@ -56,10 +56,7 @@

Problem 1: Symbols vs. strings with names

## # Now: ## data %>% select(all_of(my_variables)) ## -## See <https://tidyselect.r-lib.org/reference/faq-external-vector.html>. -## This warning is displayed once every 8 hours. -## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was -## generated. +## See <https://tidyselect.r-lib.org/reference/faq-external-vector.html>.
##   Sepal.Length Sepal.Width
 ## 1          5.1         3.5
 ## 2          4.9         3.0
@@ -67,7 +64,7 @@ 

Problem 1: Symbols vs. strings with names

## 4 4.6 3.1 ## 5 5.0 3.6

This generates a warning. Given the tidyverse’s informative error messages, it’s wise to pay heed. Directly supplying can be ambiguous —- imagine having a column named “my_variables”. Which should be selected if we have both the column and the external variable?

-

Diagram showing the dillema that dplyr is faced with when we torment it with ambiguous selections. +

Diagram showing the dillema that dplyr is faced with when we torment it with ambiguous selections. To ensure clarity, dplyr authors suggest using dplyr::all_of(), which explicitly converts a name vector into symbols, resolving any ambiguities.

iris %>%
   select(all_of(my_variables))
From 627c236b65666461f65787955707f99ee24ff644 Mon Sep 17 00:00:00 2001 From: Laura Date: Thu, 7 Sep 2023 20:57:42 +0200 Subject: [PATCH 5/9] ToC and headings' fix --- .../index.Rmd | 10 +++++-- .../index.html | 30 ++++++++++++++----- 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/index.Rmd b/content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/index.Rmd index d77cc80..d748fee 100644 --- a/content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/index.Rmd +++ b/content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/index.Rmd @@ -5,9 +5,13 @@ date: '2023-01-30' slug: r-basic-advanceds-variables-and-names-in-dplyr categories: ['Tutorial'] tags: ['r', 'tutorial', 'dplyr', 'environments', 'rlang'] +description: "TODO." +output: + blogdown::html_page: + toc: true --- -# Intro +## Intro Hello everyone! After an extended hiatus for various reasons (from graduating college to navigating job changes and legal challenges), we're back and eager to breathe new life into this blog. Given my deep interest in the fundamentals of advanced methods, today we're delving into an essential topic every dplyr user will eventually face. @@ -23,7 +27,7 @@ library(dplyr) iris <- iris %>% slice(1:5) ``` -# Problem 1: Symbols vs. strings with names +## Problem 1: Symbols vs. strings with names Let's compare how we select columns in a data frame using base R versus dplyr: @@ -119,7 +123,7 @@ my_subset_with_symbols(iris, Petal.Length, Sepal.Width) In this way we let dplyr know that `my_var_as_symbol` has to be passed directly as user provided it. We can think of embracing as of cut-paste operation. We tell dplyr: "Take what user provided in place of `my_var_as_symbol` in function call and plug it directly into `select`, without creating any intermediate variables.". Call to `my_subset_with_symbols()` is basically replaced with what lies inside of it. -# Problem 3: dynamic columns in purrr formulas in `across` +## Problem 3: dynamic columns in purrr formulas in `across` While the above solutions work seamlessly with functions like `dplyr::select()`, challenges arise when operations grow complex. Suppose we wish to craft a function, `do_magic`, that takes data, a special `column`, and several `others` columns. This function should add the special column to all others. diff --git a/content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/index.html b/content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/index.html index 3a9edab..01a0d47 100644 --- a/content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/index.html +++ b/content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/index.html @@ -5,19 +5,33 @@ slug: r-basic-advanceds-variables-and-names-in-dplyr categories: ['Tutorial'] tags: ['r', 'tutorial', 'dplyr', 'environments', 'rlang'] +description: "TODO." +output: + blogdown::html_page: + toc: true --- + -
-

Intro

+
+

Intro

Hello everyone! After an extended hiatus for various reasons (from graduating college to navigating job changes and legal challenges), we’re back and eager to breathe new life into this blog. Given my deep interest in the fundamentals of advanced methods, today we’re delving into an essential topic every dplyr user will eventually face.

dplyr is meticulously designed with the primary goal of making code workflows read as naturally and close to plain language as possible. This design philosophy manifests in two critical dimensions: semantic and syntactic.

Semantically, the emphasis is on employing words with intuitive and easily understood meanings. For instance, dplyr and its friends adhere to a robust naming convention where function names typically take on verb forms, elucidating the action they perform.

Syntactically, the arrangement and combination of these descriptive words is paramount. Arguably, this is even more critical to the user experience. One of the most evident manifestations of this syntactical approach is the tidyverse’s hallmark feature: the pipe operator. But we are not going to tackle this today. I will look into caveats of another essential and intuitive syntactic feature: the use of symbols instead of strings to refer to variables within datasets. This offers a more natural-feeling mode of interaction but, as I have found out over many years of using R, this feature can lead to some problems.

-
-

Problem 1: Symbols vs. strings with names

+
+

Problem 1: Symbols vs. strings with names

Let’s compare how we select columns in a data frame using base R versus dplyr:

# base
 iris[, c("Sepal.Length", "Sepal.Width")]
@@ -74,6 +88,7 @@ 

Problem 1: Symbols vs. strings with names

## 3 4.7 3.2 ## 4 4.6 3.1 ## 5 5.0 3.6
+

Problem 2: Passing column names as arguments to custom functions

Differentiating between passing a variable name or a symbol becomes trickier when constructing functions that internally use dplyr verbs. Consider:

@@ -100,9 +115,8 @@

Problem 2: Passing column names as arguments to custom functions

my_subset_with_symbols(iris, Petal.Length, Sepal.Width)

In this way we let dplyr know that my_var_as_symbol has to be passed directly as user provided it. We can think of embracing as of cut-paste operation. We tell dplyr: “Take what user provided in place of my_var_as_symbol in function call and plug it directly into select, without creating any intermediate variables.”. Call to my_subset_with_symbols() is basically replaced with what lies inside of it.

-
-
-

Problem 3: dynamic columns in purrr formulas in across

+
+

Problem 3: dynamic columns in purrr formulas in across

While the above solutions work seamlessly with functions like dplyr::select(), challenges arise when operations grow complex. Suppose we wish to craft a function, do_magic, that takes data, a special column, and several others columns. This function should add the special column to all others.

Leveraging dplyr::mutate(dplyr::across()) can achieve this. Its syntax is:

mutate(across(columns_to_mutate, function_to_apply))
@@ -148,6 +162,7 @@

Tip: when all_of() does not work, use .data

## 5 3.6 2.2 1.4 0.2 setosa

When you need to reference the underlying data within the context of functions, the .data pronoun comes to the rescue. As demonstrated, it operates similarly to directly accessing the data.

+

Summary & Next Steps

Throughout this post, we ventured deep into some of the intricacies of dplyr. We’ve unraveled how the package strives to make our code both semantic and syntactic, all while simplifying complex operations. The power of symbols and the utility of functions like all_of() and .data demonstrate just how dynamic and adaptable dplyr can be, especially when working with variable column names. While we’ve covered much ground, the world of dplyr is vast and constantly evolving. We are aware that all this embracing and tidyselect rules might be intimidating, but we will be continue to explore more facets of the tidyverse in future posts of “basic advanceds”, aiming to empower you with advanced techniques that enhance your data analysis journey.

@@ -158,4 +173,3 @@

Summary & Next Steps

Dive Deeper: Resources for the Curious Minds:

For those wishing to delve further or who may have lingering questions: Dplyr official programming guide

-
From 239acf8decc33f97b3033f0fa4a5ac9e25c5d215 Mon Sep 17 00:00:00 2001 From: Laura Date: Thu, 7 Sep 2023 22:52:56 +0200 Subject: [PATCH 6/9] proofreading --- .../index.Rmd | 12 ++++++------ .../index.html | 14 +++++++------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/index.Rmd b/content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/index.Rmd index d748fee..67770dc 100644 --- a/content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/index.Rmd +++ b/content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/index.Rmd @@ -15,7 +15,7 @@ output: Hello everyone! After an extended hiatus for various reasons (from graduating college to navigating job changes and legal challenges), we're back and eager to breathe new life into this blog. Given my deep interest in the fundamentals of advanced methods, today we're delving into an essential topic every dplyr user will eventually face. -dplyr is meticulously designed with the primary goal of making code workflows read as naturally and close to plain language as possible. This design philosophy manifests in two critical dimensions: *semantic* and *syntactic*. +dplyr is meticulously designed with the primary goal of making code workflows read possibly close to natural languages. This design philosophy manifests in two critical dimensions: *semantic* and *syntactic*. Semantically, the emphasis is on **employing words with intuitive and easily understood meanings**. For instance, dplyr and its friends adhere to a robust naming convention where function names typically take on verb forms, elucidating the action they perform. @@ -72,7 +72,7 @@ iris %>% select(my_variables) ``` -This generates a warning. Given the tidyverse's informative error messages, it's wise to pay heed. Directly supplying can be ambiguous —- imagine having a column named "my_variables". Which should be selected if we have both the column and the external variable? +This generates a warning. Given the tidyverse's informative error messages, it's wise to pay heed. Directly supplying can be ambiguous -- imagine having a column named `my_variable`. Which should be selected if we have both the column and the external variable? ![Diagram showing the dillema that dplyr is faced with when we torment it with ambiguous selections.](images/selection-ambiguity.png) @@ -108,7 +108,7 @@ my_subset_with_strings <- function(data, my_var_as_string) { my_subset_with_strings(iris, c("Sepal.Length", "Sepal.Width")) ``` -If we want to use symbols, just like directly in dplyr functions (mostly when those columns to use are predefined, in our internal functions or analyses), we have to *embrace* the variable: +If we want to use symbols, just like directly in dplyr functions (mostly when those columns to use are predefined, be it in our internal functions or in analyses), we have to *embrace* the variable: ```{r, eval=FALSE} my_subset_with_symbols <- function(data, my_var_as_symbol) { @@ -123,7 +123,7 @@ my_subset_with_symbols(iris, Petal.Length, Sepal.Width) In this way we let dplyr know that `my_var_as_symbol` has to be passed directly as user provided it. We can think of embracing as of cut-paste operation. We tell dplyr: "Take what user provided in place of `my_var_as_symbol` in function call and plug it directly into `select`, without creating any intermediate variables.". Call to `my_subset_with_symbols()` is basically replaced with what lies inside of it. -## Problem 3: dynamic columns in purrr formulas in `across` +## Problem 3: Dynamic columns in purrr formulas in `across` While the above solutions work seamlessly with functions like `dplyr::select()`, challenges arise when operations grow complex. Suppose we wish to craft a function, `do_magic`, that takes data, a special `column`, and several `others` columns. This function should add the special column to all others. @@ -182,7 +182,7 @@ When you need to reference the underlying data within the context of functions, ## Summary & Next Steps -Throughout this post, we ventured deep into some of the intricacies of dplyr. We've unraveled how the package strives to make our code both semantic and syntactic, all while simplifying complex operations. The power of symbols and the utility of functions like `all_of()` and `.data` demonstrate just how dynamic and adaptable dplyr can be, especially when working with variable column names. While we've covered much ground, the world of dplyr is vast and constantly evolving. We are aware that all this *embracing* and *tidyselect* rules might be intimidating, but we will be continue to explore more facets of the tidyverse in future posts of "basic advanceds", aiming to empower you with advanced techniques that enhance your data analysis journey. +Throughout this post, we ventured deep into some of the intricacies of dplyr. We've unraveled how the package strives to make our code both semantic and syntactic, all while simplifying complex operations. The power of symbols and the utility of functions like `all_of()` and `.data` demonstrate just how dynamic and adaptable dplyr can be, especially when working with variable column names. While we've covered much ground, the world of dplyr is vast and constantly evolving. We are aware that all this *embracing* and *tidyselect* rules might be intimidating, but we will continue to explore more facets of the tidyverse in future posts of "basic advanceds", aiming to empower you with advanced techniques that enhance your data analysis journey. If you've found this post enlightening and wish to delve deeper, or if you have any questions or insights, we'd love to hear from you! You can contact us directly via [X](https://twitter.com/Rturtletopia). Alternatively, for those who prefer a more open-source avenue, feel free to open an issue on our [GitHub](https://github.com/turtletopia/turtletopia.github.io/issues) repository. Your feedback and insights not only help us improve, but they also contribute to the broader data science community. @@ -190,4 +190,4 @@ Until next time, keep exploring, learning, and sharing! ## Dive Deeper: Resources for the Curious Minds: -For those wishing to delve further or who may have lingering questions: [Dplyr official programming guide](https://dplyr.tidyverse.org/articles/programming.html) +For those wishing to delve further or who may have lingering questions: [dplyr official programming guide](https://dplyr.tidyverse.org/articles/programming.html) diff --git a/content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/index.html b/content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/index.html index 01a0d47..17c5d2c 100644 --- a/content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/index.html +++ b/content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/index.html @@ -17,7 +17,7 @@
  • Intro
  • Problem 1: Symbols vs. strings with names
  • Problem 2: Passing column names as arguments to custom functions
  • -
  • Problem 3: dynamic columns in purrr formulas in across
  • +
  • Problem 3: Dynamic columns in purrr formulas in across
  • Summary & Next Steps
  • Dive Deeper: Resources for the Curious Minds:
  • @@ -26,7 +26,7 @@

    Intro

    Hello everyone! After an extended hiatus for various reasons (from graduating college to navigating job changes and legal challenges), we’re back and eager to breathe new life into this blog. Given my deep interest in the fundamentals of advanced methods, today we’re delving into an essential topic every dplyr user will eventually face.

    -

    dplyr is meticulously designed with the primary goal of making code workflows read as naturally and close to plain language as possible. This design philosophy manifests in two critical dimensions: semantic and syntactic.

    +

    dplyr is meticulously designed with the primary goal of making code workflows read possibly close to natural languages. This design philosophy manifests in two critical dimensions: semantic and syntactic.

    Semantically, the emphasis is on employing words with intuitive and easily understood meanings. For instance, dplyr and its friends adhere to a robust naming convention where function names typically take on verb forms, elucidating the action they perform.

    Syntactically, the arrangement and combination of these descriptive words is paramount. Arguably, this is even more critical to the user experience. One of the most evident manifestations of this syntactical approach is the tidyverse’s hallmark feature: the pipe operator. But we are not going to tackle this today. I will look into caveats of another essential and intuitive syntactic feature: the use of symbols instead of strings to refer to variables within datasets. This offers a more natural-feeling mode of interaction but, as I have found out over many years of using R, this feature can lead to some problems.

    @@ -77,7 +77,7 @@

    Problem 1: Symbols vs. strings with names

    ## 3 4.7 3.2 ## 4 4.6 3.1 ## 5 5.0 3.6 -

    This generates a warning. Given the tidyverse’s informative error messages, it’s wise to pay heed. Directly supplying can be ambiguous —- imagine having a column named “my_variables”. Which should be selected if we have both the column and the external variable?

    +

    This generates a warning. Given the tidyverse’s informative error messages, it’s wise to pay heed. Directly supplying can be ambiguous – imagine having a column named my_variable. Which should be selected if we have both the column and the external variable?

    Diagram showing the dillema that dplyr is faced with when we torment it with ambiguous selections. To ensure clarity, dplyr authors suggest using dplyr::all_of(), which explicitly converts a name vector into symbols, resolving any ambiguities.

    iris %>%
    @@ -104,7 +104,7 @@ 

    Problem 2: Passing column names as arguments to custom functions

    } my_subset_with_strings(iris, c("Sepal.Length", "Sepal.Width"))
    -

    If we want to use symbols, just like directly in dplyr functions (mostly when those columns to use are predefined, in our internal functions or analyses), we have to embrace the variable:

    +

    If we want to use symbols, just like directly in dplyr functions (mostly when those columns to use are predefined, be it in our internal functions or in analyses), we have to embrace the variable:

    my_subset_with_symbols <- function(data, my_var_as_symbol) {
       data %>%
         select({{ my_var_as_symbol }})
    @@ -116,7 +116,7 @@ 

    Problem 2: Passing column names as arguments to custom functions

    In this way we let dplyr know that my_var_as_symbol has to be passed directly as user provided it. We can think of embracing as of cut-paste operation. We tell dplyr: “Take what user provided in place of my_var_as_symbol in function call and plug it directly into select, without creating any intermediate variables.”. Call to my_subset_with_symbols() is basically replaced with what lies inside of it.

    -

    Problem 3: dynamic columns in purrr formulas in across

    +

    Problem 3: Dynamic columns in purrr formulas in across

    While the above solutions work seamlessly with functions like dplyr::select(), challenges arise when operations grow complex. Suppose we wish to craft a function, do_magic, that takes data, a special column, and several others columns. This function should add the special column to all others.

    Leveraging dplyr::mutate(dplyr::across()) can achieve this. Its syntax is:

    mutate(across(columns_to_mutate, function_to_apply))
    @@ -165,11 +165,11 @@

    Tip: when all_of() does not work, use .data

    Summary & Next Steps

    -

    Throughout this post, we ventured deep into some of the intricacies of dplyr. We’ve unraveled how the package strives to make our code both semantic and syntactic, all while simplifying complex operations. The power of symbols and the utility of functions like all_of() and .data demonstrate just how dynamic and adaptable dplyr can be, especially when working with variable column names. While we’ve covered much ground, the world of dplyr is vast and constantly evolving. We are aware that all this embracing and tidyselect rules might be intimidating, but we will be continue to explore more facets of the tidyverse in future posts of “basic advanceds”, aiming to empower you with advanced techniques that enhance your data analysis journey.

    +

    Throughout this post, we ventured deep into some of the intricacies of dplyr. We’ve unraveled how the package strives to make our code both semantic and syntactic, all while simplifying complex operations. The power of symbols and the utility of functions like all_of() and .data demonstrate just how dynamic and adaptable dplyr can be, especially when working with variable column names. While we’ve covered much ground, the world of dplyr is vast and constantly evolving. We are aware that all this embracing and tidyselect rules might be intimidating, but we will continue to explore more facets of the tidyverse in future posts of “basic advanceds”, aiming to empower you with advanced techniques that enhance your data analysis journey.

    If you’ve found this post enlightening and wish to delve deeper, or if you have any questions or insights, we’d love to hear from you! You can contact us directly via X. Alternatively, for those who prefer a more open-source avenue, feel free to open an issue on our GitHub repository. Your feedback and insights not only help us improve, but they also contribute to the broader data science community.

    Until next time, keep exploring, learning, and sharing!

    Dive Deeper: Resources for the Curious Minds:

    -

    For those wishing to delve further or who may have lingering questions: Dplyr official programming guide

    +

    For those wishing to delve further or who may have lingering questions: dplyr official programming guide

    From 6ec46a1677639ffa9d1a8cfbe65e6f4cf35a9d8e Mon Sep 17 00:00:00 2001 From: DominikRafacz Date: Wed, 19 Mar 2025 19:32:56 +0100 Subject: [PATCH 7/9] change image path to local --- .../index.Rmd | 4 +++- .../index.html | 21 ++++++++++++------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/index.Rmd b/content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/index.Rmd index 67770dc..44921b8 100644 --- a/content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/index.Rmd +++ b/content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/index.Rmd @@ -9,6 +9,8 @@ description: "TODO." output: blogdown::html_page: toc: true +images: + - selection-ambiguity.png --- ## Intro @@ -75,7 +77,7 @@ iris %>% This generates a warning. Given the tidyverse's informative error messages, it's wise to pay heed. Directly supplying can be ambiguous -- imagine having a column named `my_variable`. Which should be selected if we have both the column and the external variable? -![Diagram showing the dillema that dplyr is faced with when we torment it with ambiguous selections.](images/selection-ambiguity.png) +![Diagram showing the dillema that dplyr is faced with when we torment it with ambiguous selections.](selection-ambiguity.png) To ensure clarity, dplyr authors suggest using dplyr::all_of(), which explicitly converts a name vector into symbols, resolving any ambiguities. ```{r warning=TRUE} diff --git a/content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/index.html b/content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/index.html index 17c5d2c..d8b841a 100644 --- a/content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/index.html +++ b/content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/index.html @@ -9,17 +9,19 @@ output: blogdown::html_page: toc: true +images: + - selection-ambiguity.png --- @@ -70,7 +72,10 @@

    Problem 1: Symbols vs. strings with names

    ## # Now: ## data %>% select(all_of(my_variables)) ## -## See <https://tidyselect.r-lib.org/reference/faq-external-vector.html>.
    +## See <https://tidyselect.r-lib.org/reference/faq-external-vector.html>. +## This warning is displayed once every 8 hours. +## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was +## generated.
    ##   Sepal.Length Sepal.Width
     ## 1          5.1         3.5
     ## 2          4.9         3.0
    @@ -78,7 +83,7 @@ 

    Problem 1: Symbols vs. strings with names

    ## 4 4.6 3.1 ## 5 5.0 3.6

    This generates a warning. Given the tidyverse’s informative error messages, it’s wise to pay heed. Directly supplying can be ambiguous – imagine having a column named my_variable. Which should be selected if we have both the column and the external variable?

    -

    Diagram showing the dillema that dplyr is faced with when we torment it with ambiguous selections. +

    Diagram showing the dillema that dplyr is faced with when we torment it with ambiguous selections. To ensure clarity, dplyr authors suggest using dplyr::all_of(), which explicitly converts a name vector into symbols, resolving any ambiguities.

    iris %>%
       select(all_of(my_variables))
    From c3aa14fd1407989129093674d4d747e59a1abf42 Mon Sep 17 00:00:00 2001 From: DominikRafacz Date: Wed, 19 Mar 2025 19:46:05 +0100 Subject: [PATCH 8/9] update date on the post --- .../images/selection-ambiguity.png | Bin .../images/selection-ambiguity.svg | 0 .../index.Rmd | 2 +- .../index.html | 360 +++++++++--------- 4 files changed, 181 insertions(+), 181 deletions(-) rename content/post/{2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr => 2025-03-19-r-basic-advanceds-variables-and-names-in-dplyr}/images/selection-ambiguity.png (100%) rename content/post/{2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr => 2025-03-19-r-basic-advanceds-variables-and-names-in-dplyr}/images/selection-ambiguity.svg (100%) rename content/post/{2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr => 2025-03-19-r-basic-advanceds-variables-and-names-in-dplyr}/index.Rmd (99%) rename content/post/{2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr => 2025-03-19-r-basic-advanceds-variables-and-names-in-dplyr}/index.html (98%) diff --git a/content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/images/selection-ambiguity.png b/content/post/2025-03-19-r-basic-advanceds-variables-and-names-in-dplyr/images/selection-ambiguity.png similarity index 100% rename from content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/images/selection-ambiguity.png rename to content/post/2025-03-19-r-basic-advanceds-variables-and-names-in-dplyr/images/selection-ambiguity.png diff --git a/content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/images/selection-ambiguity.svg b/content/post/2025-03-19-r-basic-advanceds-variables-and-names-in-dplyr/images/selection-ambiguity.svg similarity index 100% rename from content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/images/selection-ambiguity.svg rename to content/post/2025-03-19-r-basic-advanceds-variables-and-names-in-dplyr/images/selection-ambiguity.svg diff --git a/content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/index.Rmd b/content/post/2025-03-19-r-basic-advanceds-variables-and-names-in-dplyr/index.Rmd similarity index 99% rename from content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/index.Rmd rename to content/post/2025-03-19-r-basic-advanceds-variables-and-names-in-dplyr/index.Rmd index 44921b8..c53de95 100644 --- a/content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/index.Rmd +++ b/content/post/2025-03-19-r-basic-advanceds-variables-and-names-in-dplyr/index.Rmd @@ -1,7 +1,7 @@ --- title: 'R Basic Advanceds: Variables and Names in dplyr' author: Dominik Rafacz -date: '2023-01-30' +date: '2025-03-19' slug: r-basic-advanceds-variables-and-names-in-dplyr categories: ['Tutorial'] tags: ['r', 'tutorial', 'dplyr', 'environments', 'rlang'] diff --git a/content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/index.html b/content/post/2025-03-19-r-basic-advanceds-variables-and-names-in-dplyr/index.html similarity index 98% rename from content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/index.html rename to content/post/2025-03-19-r-basic-advanceds-variables-and-names-in-dplyr/index.html index d8b841a..024af44 100644 --- a/content/post/2023-01-30-r-basic-advanceds-variables-and-names-in-dplyr/index.html +++ b/content/post/2025-03-19-r-basic-advanceds-variables-and-names-in-dplyr/index.html @@ -1,180 +1,180 @@ ---- -title: 'R Basic Advanceds: Variables and Names in dplyr' -author: Dominik Rafacz -date: '2023-01-30' -slug: r-basic-advanceds-variables-and-names-in-dplyr -categories: ['Tutorial'] -tags: ['r', 'tutorial', 'dplyr', 'environments', 'rlang'] -description: "TODO." -output: - blogdown::html_page: - toc: true -images: - - selection-ambiguity.png ---- - - - - -
    -

    Intro

    -

    Hello everyone! After an extended hiatus for various reasons (from graduating college to navigating job changes and legal challenges), we’re back and eager to breathe new life into this blog. Given my deep interest in the fundamentals of advanced methods, today we’re delving into an essential topic every dplyr user will eventually face.

    -

    dplyr is meticulously designed with the primary goal of making code workflows read possibly close to natural languages. This design philosophy manifests in two critical dimensions: semantic and syntactic.

    -

    Semantically, the emphasis is on employing words with intuitive and easily understood meanings. For instance, dplyr and its friends adhere to a robust naming convention where function names typically take on verb forms, elucidating the action they perform.

    -

    Syntactically, the arrangement and combination of these descriptive words is paramount. Arguably, this is even more critical to the user experience. One of the most evident manifestations of this syntactical approach is the tidyverse’s hallmark feature: the pipe operator. But we are not going to tackle this today. I will look into caveats of another essential and intuitive syntactic feature: the use of symbols instead of strings to refer to variables within datasets. This offers a more natural-feeling mode of interaction but, as I have found out over many years of using R, this feature can lead to some problems.

    -
    -
    -

    Problem 1: Symbols vs. strings with names

    -

    Let’s compare how we select columns in a data frame using base R versus dplyr:

    -
    # base
    -iris[, c("Sepal.Length", "Sepal.Width")]
    -
    -# dplyr
    -iris %>%
    -  select(Sepal.Length, Sepal.Width)
    -

    Notice the difference:

    -
      -
    • In base R, we use "Sepal.Length", "Sepal.Width", which are strings enclosed in quotes (single and double quotes are both valid).
    • -
    • With dplyr, we have Sepal.Length, Sepal.Width, unquoted symbols.
    • -
    -

    In the second case symbols are used to access columns in a data frame, just like we use symbols to access any variable or function that we store in our top-level environments. -It is vital to grasp this distinction to sidestep potential pitfalls. which I will discuss in the rest of the post.

    -

    So, what symbols actually are? We use them as names of objects and this is the identity of their core. This is why it feels natural to use them to not only access top-level variables, but also variables in data. There is more to the nature of symbols, but we will come back to that later.

    -

    Notice that dplyr is smart enough to let you select variables by strings as well:

    -
    iris %>%
    -  select("Sepal.Length", "Sepal.Width")
    -
    ##   Sepal.Length Sepal.Width
    -## 1          5.1         3.5
    -## 2          4.9         3.0
    -## 3          4.7         3.2
    -## 4          4.6         3.1
    -## 5          5.0         3.6
    -

    This is, however, inadvisable, as this is exactly what tidyverse designers wanted to avoid.

    -

    Now, consider a scenario where we have an external variable storing column names:

    -
    my_variables <- c("Sepal.Length", "Sepal.Width")
    -

    Although it might seem intuitive to directly supply it to select:

    -
    iris %>%
    -  select(my_variables)
    -
    ## Warning: Using an external vector in selections was deprecated in tidyselect 1.1.0.
    -## ℹ Please use `all_of()` or `any_of()` instead.
    -##   # Was:
    -##   data %>% select(my_variables)
    -## 
    -##   # Now:
    -##   data %>% select(all_of(my_variables))
    -## 
    -## See <https://tidyselect.r-lib.org/reference/faq-external-vector.html>.
    -## This warning is displayed once every 8 hours.
    -## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
    -## generated.
    -
    ##   Sepal.Length Sepal.Width
    -## 1          5.1         3.5
    -## 2          4.9         3.0
    -## 3          4.7         3.2
    -## 4          4.6         3.1
    -## 5          5.0         3.6
    -

    This generates a warning. Given the tidyverse’s informative error messages, it’s wise to pay heed. Directly supplying can be ambiguous – imagine having a column named my_variable. Which should be selected if we have both the column and the external variable?

    -

    Diagram showing the dillema that dplyr is faced with when we torment it with ambiguous selections. -To ensure clarity, dplyr authors suggest using dplyr::all_of(), which explicitly converts a name vector into symbols, resolving any ambiguities.

    -
    iris %>%
    -  select(all_of(my_variables))
    -
    ##   Sepal.Length Sepal.Width
    -## 1          5.1         3.5
    -## 2          4.9         3.0
    -## 3          4.7         3.2
    -## 4          4.6         3.1
    -## 5          5.0         3.6
    -
    -
    -

    Problem 2: Passing column names as arguments to custom functions

    -

    Differentiating between passing a variable name or a symbol becomes trickier when constructing functions that internally use dplyr verbs. Consider:

    -
    my_subset <- function(data, my_var) {
    -  data %>%
    -    select(my_var)
    -}
    -

    This might cause a lot of issues. Should we provide a string as a name (my_subset(iris, "Sepal.Length")) or a symbol (my_subset(iris, Sepal.Length))? To answer this question, we should first be clear about our intent (it would be nice to write a few words of documentation – for other users or for ourselves in the future). Both approaches are possible and valid. It is important to choose one and remain consistent across all functions that we write.

    -

    For instances where column names are passed as strings (common in Shiny apps when columns are selected by some input), one could utilize the previously discussed dplyr::all_of():

    -
    my_subset_with_strings <- function(data, my_var_as_string) {
    -  data %>%
    -    select(all_of(my_var_as_string))
    -}
    -
    -my_subset_with_strings(iris, c("Sepal.Length", "Sepal.Width"))
    -

    If we want to use symbols, just like directly in dplyr functions (mostly when those columns to use are predefined, be it in our internal functions or in analyses), we have to embrace the variable:

    -
    my_subset_with_symbols <- function(data, my_var_as_symbol) {
    -  data %>%
    -    select({{ my_var_as_symbol }})
    -}
    -
    -my_subset_with_symbols(iris, Petal.Length)
    -
    -my_subset_with_symbols(iris, Petal.Length, Sepal.Width)
    -

    In this way we let dplyr know that my_var_as_symbol has to be passed directly as user provided it. We can think of embracing as of cut-paste operation. We tell dplyr: “Take what user provided in place of my_var_as_symbol in function call and plug it directly into select, without creating any intermediate variables.”. Call to my_subset_with_symbols() is basically replaced with what lies inside of it.

    -
    -
    -

    Problem 3: Dynamic columns in purrr formulas in across

    -

    While the above solutions work seamlessly with functions like dplyr::select(), challenges arise when operations grow complex. Suppose we wish to craft a function, do_magic, that takes data, a special column, and several others columns. This function should add the special column to all others.

    -

    Leveraging dplyr::mutate(dplyr::across()) can achieve this. Its syntax is:

    -
    mutate(across(columns_to_mutate, function_to_apply))
    -

    For custom, unnamed functions, the purrr formula syntax (~ expression with .x) is beneficial. In our case (without enclosing it in a function yet) could look like:

    -
    iris %>%
    -  mutate(across(all_of(c("Sepal.Length", "Sepal.Width")), ~ .x - Petal.Length))
    -

    Elegant, isn’t it? Now, let’s proceed by encapsulating this logic within a function where column names are passed as strings:

    -
    do_magic <- function(data, special, others) {
    -  data %>%
    -    mutate(across(all_of(others), ~ .x - all_of(special)))
    -}
    -
    -# won't work:
    -# do_magic(iris, special = "Petal.Length", others = c("Sepal.Length", "Sepal.Width"))
    -

    Surprisingly, it fails! When used within the context of across, dplyr seems unable to utilize the tidyselect rules (the ones that make all_of() possible). But we’re not defeated; let’s try embracing:

    -
    do_magic_but_better <- function(data, special, others) {
    -  data %>%
    -    mutate(across(all_of(others), ~ .x - {{special}}))
    -}
    -
    -do_magic_but_better(iris, special = Petal.Length, others = c("Sepal.Length", "Sepal.Width"))
    -
    ##   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
    -## 1          3.7         2.1          1.4         0.2  setosa
    -## 2          3.5         1.6          1.4         0.2  setosa
    -## 3          3.4         1.9          1.3         0.2  setosa
    -## 4          3.1         1.6          1.5         0.2  setosa
    -## 5          3.6         2.2          1.4         0.2  setosa
    -

    By adopting this approach, it’s imperative to provide special as a symbol. Also, this does not look fine: one parameter is provided as symbol, another one is as character vector… We should always aim at being consistent. Either all column-like parameters should be symbols or all should be character strings. There are pros and cons to both ways. Let’s say that we want to stick to strings only. How can we do it?

    -
    -

    Tip: when all_of() does not work, use .data

    -

    There’s a workaround for this conundrum:

    -
    do_magic_but_in_other_way <- function(data, special, others) {
    -  data %>%
    -    mutate(across(all_of(others), ~ .x - .data[[special]]))
    -}
    -
    -do_magic_but_in_other_way(iris, special = "Petal.Length", others = c("Sepal.Length", "Sepal.Width"))
    -
    ##   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
    -## 1          3.7         2.1          1.4         0.2  setosa
    -## 2          3.5         1.6          1.4         0.2  setosa
    -## 3          3.4         1.9          1.3         0.2  setosa
    -## 4          3.1         1.6          1.5         0.2  setosa
    -## 5          3.6         2.2          1.4         0.2  setosa
    -

    When you need to reference the underlying data within the context of functions, the .data pronoun comes to the rescue. As demonstrated, it operates similarly to directly accessing the data.

    -
    -
    -
    -

    Summary & Next Steps

    -

    Throughout this post, we ventured deep into some of the intricacies of dplyr. We’ve unraveled how the package strives to make our code both semantic and syntactic, all while simplifying complex operations. The power of symbols and the utility of functions like all_of() and .data demonstrate just how dynamic and adaptable dplyr can be, especially when working with variable column names. While we’ve covered much ground, the world of dplyr is vast and constantly evolving. We are aware that all this embracing and tidyselect rules might be intimidating, but we will continue to explore more facets of the tidyverse in future posts of “basic advanceds”, aiming to empower you with advanced techniques that enhance your data analysis journey.

    -

    If you’ve found this post enlightening and wish to delve deeper, or if you have any questions or insights, we’d love to hear from you! You can contact us directly via X. Alternatively, for those who prefer a more open-source avenue, feel free to open an issue on our GitHub repository. Your feedback and insights not only help us improve, but they also contribute to the broader data science community.

    -

    Until next time, keep exploring, learning, and sharing!

    -
    -
    -

    Dive Deeper: Resources for the Curious Minds:

    -

    For those wishing to delve further or who may have lingering questions: dplyr official programming guide

    -
    +--- +title: 'R Basic Advanceds: Variables and Names in dplyr' +author: Dominik Rafacz +date: '2025-03-19' +slug: r-basic-advanceds-variables-and-names-in-dplyr +categories: ['Tutorial'] +tags: ['r', 'tutorial', 'dplyr', 'environments', 'rlang'] +description: "TODO." +output: + blogdown::html_page: + toc: true +images: + - selection-ambiguity.png +--- + + + + +
    +

    Intro

    +

    Hello everyone! After an extended hiatus for various reasons (from graduating college to navigating job changes and legal challenges), we’re back and eager to breathe new life into this blog. Given my deep interest in the fundamentals of advanced methods, today we’re delving into an essential topic every dplyr user will eventually face.

    +

    dplyr is meticulously designed with the primary goal of making code workflows read possibly close to natural languages. This design philosophy manifests in two critical dimensions: semantic and syntactic.

    +

    Semantically, the emphasis is on employing words with intuitive and easily understood meanings. For instance, dplyr and its friends adhere to a robust naming convention where function names typically take on verb forms, elucidating the action they perform.

    +

    Syntactically, the arrangement and combination of these descriptive words is paramount. Arguably, this is even more critical to the user experience. One of the most evident manifestations of this syntactical approach is the tidyverse’s hallmark feature: the pipe operator. But we are not going to tackle this today. I will look into caveats of another essential and intuitive syntactic feature: the use of symbols instead of strings to refer to variables within datasets. This offers a more natural-feeling mode of interaction but, as I have found out over many years of using R, this feature can lead to some problems.

    +
    +
    +

    Problem 1: Symbols vs. strings with names

    +

    Let’s compare how we select columns in a data frame using base R versus dplyr:

    +
    # base
    +iris[, c("Sepal.Length", "Sepal.Width")]
    +
    +# dplyr
    +iris %>%
    +  select(Sepal.Length, Sepal.Width)
    +

    Notice the difference:

    +
      +
    • In base R, we use "Sepal.Length", "Sepal.Width", which are strings enclosed in quotes (single and double quotes are both valid).
    • +
    • With dplyr, we have Sepal.Length, Sepal.Width, unquoted symbols.
    • +
    +

    In the second case symbols are used to access columns in a data frame, just like we use symbols to access any variable or function that we store in our top-level environments. +It is vital to grasp this distinction to sidestep potential pitfalls. which I will discuss in the rest of the post.

    +

    So, what symbols actually are? We use them as names of objects and this is the identity of their core. This is why it feels natural to use them to not only access top-level variables, but also variables in data. There is more to the nature of symbols, but we will come back to that later.

    +

    Notice that dplyr is smart enough to let you select variables by strings as well:

    +
    iris %>%
    +  select("Sepal.Length", "Sepal.Width")
    +
    ##   Sepal.Length Sepal.Width
    +## 1          5.1         3.5
    +## 2          4.9         3.0
    +## 3          4.7         3.2
    +## 4          4.6         3.1
    +## 5          5.0         3.6
    +

    This is, however, inadvisable, as this is exactly what tidyverse designers wanted to avoid.

    +

    Now, consider a scenario where we have an external variable storing column names:

    +
    my_variables <- c("Sepal.Length", "Sepal.Width")
    +

    Although it might seem intuitive to directly supply it to select:

    +
    iris %>%
    +  select(my_variables)
    +
    ## Warning: Using an external vector in selections was deprecated in tidyselect 1.1.0.
    +## ℹ Please use `all_of()` or `any_of()` instead.
    +##   # Was:
    +##   data %>% select(my_variables)
    +## 
    +##   # Now:
    +##   data %>% select(all_of(my_variables))
    +## 
    +## See <https://tidyselect.r-lib.org/reference/faq-external-vector.html>.
    +## This warning is displayed once every 8 hours.
    +## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
    +## generated.
    +
    ##   Sepal.Length Sepal.Width
    +## 1          5.1         3.5
    +## 2          4.9         3.0
    +## 3          4.7         3.2
    +## 4          4.6         3.1
    +## 5          5.0         3.6
    +

    This generates a warning. Given the tidyverse’s informative error messages, it’s wise to pay heed. Directly supplying can be ambiguous – imagine having a column named my_variable. Which should be selected if we have both the column and the external variable?

    +

    Diagram showing the dillema that dplyr is faced with when we torment it with ambiguous selections. +To ensure clarity, dplyr authors suggest using dplyr::all_of(), which explicitly converts a name vector into symbols, resolving any ambiguities.

    +
    iris %>%
    +  select(all_of(my_variables))
    +
    ##   Sepal.Length Sepal.Width
    +## 1          5.1         3.5
    +## 2          4.9         3.0
    +## 3          4.7         3.2
    +## 4          4.6         3.1
    +## 5          5.0         3.6
    +
    +
    +

    Problem 2: Passing column names as arguments to custom functions

    +

    Differentiating between passing a variable name or a symbol becomes trickier when constructing functions that internally use dplyr verbs. Consider:

    +
    my_subset <- function(data, my_var) {
    +  data %>%
    +    select(my_var)
    +}
    +

    This might cause a lot of issues. Should we provide a string as a name (my_subset(iris, "Sepal.Length")) or a symbol (my_subset(iris, Sepal.Length))? To answer this question, we should first be clear about our intent (it would be nice to write a few words of documentation – for other users or for ourselves in the future). Both approaches are possible and valid. It is important to choose one and remain consistent across all functions that we write.

    +

    For instances where column names are passed as strings (common in Shiny apps when columns are selected by some input), one could utilize the previously discussed dplyr::all_of():

    +
    my_subset_with_strings <- function(data, my_var_as_string) {
    +  data %>%
    +    select(all_of(my_var_as_string))
    +}
    +
    +my_subset_with_strings(iris, c("Sepal.Length", "Sepal.Width"))
    +

    If we want to use symbols, just like directly in dplyr functions (mostly when those columns to use are predefined, be it in our internal functions or in analyses), we have to embrace the variable:

    +
    my_subset_with_symbols <- function(data, my_var_as_symbol) {
    +  data %>%
    +    select({{ my_var_as_symbol }})
    +}
    +
    +my_subset_with_symbols(iris, Petal.Length)
    +
    +my_subset_with_symbols(iris, Petal.Length, Sepal.Width)
    +

    In this way we let dplyr know that my_var_as_symbol has to be passed directly as user provided it. We can think of embracing as of cut-paste operation. We tell dplyr: “Take what user provided in place of my_var_as_symbol in function call and plug it directly into select, without creating any intermediate variables.”. Call to my_subset_with_symbols() is basically replaced with what lies inside of it.

    +
    +
    +

    Problem 3: Dynamic columns in purrr formulas in across

    +

    While the above solutions work seamlessly with functions like dplyr::select(), challenges arise when operations grow complex. Suppose we wish to craft a function, do_magic, that takes data, a special column, and several others columns. This function should add the special column to all others.

    +

    Leveraging dplyr::mutate(dplyr::across()) can achieve this. Its syntax is:

    +
    mutate(across(columns_to_mutate, function_to_apply))
    +

    For custom, unnamed functions, the purrr formula syntax (~ expression with .x) is beneficial. In our case (without enclosing it in a function yet) could look like:

    +
    iris %>%
    +  mutate(across(all_of(c("Sepal.Length", "Sepal.Width")), ~ .x - Petal.Length))
    +

    Elegant, isn’t it? Now, let’s proceed by encapsulating this logic within a function where column names are passed as strings:

    +
    do_magic <- function(data, special, others) {
    +  data %>%
    +    mutate(across(all_of(others), ~ .x - all_of(special)))
    +}
    +
    +# won't work:
    +# do_magic(iris, special = "Petal.Length", others = c("Sepal.Length", "Sepal.Width"))
    +

    Surprisingly, it fails! When used within the context of across, dplyr seems unable to utilize the tidyselect rules (the ones that make all_of() possible). But we’re not defeated; let’s try embracing:

    +
    do_magic_but_better <- function(data, special, others) {
    +  data %>%
    +    mutate(across(all_of(others), ~ .x - {{special}}))
    +}
    +
    +do_magic_but_better(iris, special = Petal.Length, others = c("Sepal.Length", "Sepal.Width"))
    +
    ##   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
    +## 1          3.7         2.1          1.4         0.2  setosa
    +## 2          3.5         1.6          1.4         0.2  setosa
    +## 3          3.4         1.9          1.3         0.2  setosa
    +## 4          3.1         1.6          1.5         0.2  setosa
    +## 5          3.6         2.2          1.4         0.2  setosa
    +

    By adopting this approach, it’s imperative to provide special as a symbol. Also, this does not look fine: one parameter is provided as symbol, another one is as character vector… We should always aim at being consistent. Either all column-like parameters should be symbols or all should be character strings. There are pros and cons to both ways. Let’s say that we want to stick to strings only. How can we do it?

    +
    +

    Tip: when all_of() does not work, use .data

    +

    There’s a workaround for this conundrum:

    +
    do_magic_but_in_other_way <- function(data, special, others) {
    +  data %>%
    +    mutate(across(all_of(others), ~ .x - .data[[special]]))
    +}
    +
    +do_magic_but_in_other_way(iris, special = "Petal.Length", others = c("Sepal.Length", "Sepal.Width"))
    +
    ##   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
    +## 1          3.7         2.1          1.4         0.2  setosa
    +## 2          3.5         1.6          1.4         0.2  setosa
    +## 3          3.4         1.9          1.3         0.2  setosa
    +## 4          3.1         1.6          1.5         0.2  setosa
    +## 5          3.6         2.2          1.4         0.2  setosa
    +

    When you need to reference the underlying data within the context of functions, the .data pronoun comes to the rescue. As demonstrated, it operates similarly to directly accessing the data.

    +
    +
    +
    +

    Summary & Next Steps

    +

    Throughout this post, we ventured deep into some of the intricacies of dplyr. We’ve unraveled how the package strives to make our code both semantic and syntactic, all while simplifying complex operations. The power of symbols and the utility of functions like all_of() and .data demonstrate just how dynamic and adaptable dplyr can be, especially when working with variable column names. While we’ve covered much ground, the world of dplyr is vast and constantly evolving. We are aware that all this embracing and tidyselect rules might be intimidating, but we will continue to explore more facets of the tidyverse in future posts of “basic advanceds”, aiming to empower you with advanced techniques that enhance your data analysis journey.

    +

    If you’ve found this post enlightening and wish to delve deeper, or if you have any questions or insights, we’d love to hear from you! You can contact us directly via X. Alternatively, for those who prefer a more open-source avenue, feel free to open an issue on our GitHub repository. Your feedback and insights not only help us improve, but they also contribute to the broader data science community.

    +

    Until next time, keep exploring, learning, and sharing!

    +
    +
    +

    Dive Deeper: Resources for the Curious Minds:

    +

    For those wishing to delve further or who may have lingering questions: dplyr official programming guide

    +
    From 376aa177797af1ea293385d523157543349ec82f Mon Sep 17 00:00:00 2001 From: DominikRafacz Date: Wed, 19 Mar 2025 21:07:36 +0100 Subject: [PATCH 9/9] improve on the article --- .../embracing.png | Bin 0 -> 63060 bytes .../embracing.svg | 115 ++++++++++++++++++ .../index.Rmd | 84 +++++++++---- .../index.html | 78 ++++++++---- .../{images => }/selection-ambiguity.png | Bin .../{images => }/selection-ambiguity.svg | 0 6 files changed, 232 insertions(+), 45 deletions(-) create mode 100644 content/post/2025-03-19-r-basic-advanceds-variables-and-names-in-dplyr/embracing.png create mode 100644 content/post/2025-03-19-r-basic-advanceds-variables-and-names-in-dplyr/embracing.svg rename content/post/2025-03-19-r-basic-advanceds-variables-and-names-in-dplyr/{images => }/selection-ambiguity.png (100%) rename content/post/2025-03-19-r-basic-advanceds-variables-and-names-in-dplyr/{images => }/selection-ambiguity.svg (100%) diff --git a/content/post/2025-03-19-r-basic-advanceds-variables-and-names-in-dplyr/embracing.png b/content/post/2025-03-19-r-basic-advanceds-variables-and-names-in-dplyr/embracing.png new file mode 100644 index 0000000000000000000000000000000000000000..d7757d0472a4e6cb1c37b647e009b8eb89a1e42c GIT binary patch literal 63060 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�)NL30!!9O* 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 aFE^k^M8$c%L9y(!n7FWvP^Eyb-~R!roWQgI literal 0 HcmV?d00001 diff --git a/content/post/2025-03-19-r-basic-advanceds-variables-and-names-in-dplyr/embracing.svg b/content/post/2025-03-19-r-basic-advanceds-variables-and-names-in-dplyr/embracing.svg new file mode 100644 index 0000000..b53f283 --- /dev/null +++ b/content/post/2025-03-19-r-basic-advanceds-variables-and-names-in-dplyr/embracing.svg @@ -0,0 +1,115 @@ + + + + diff --git a/content/post/2025-03-19-r-basic-advanceds-variables-and-names-in-dplyr/index.Rmd b/content/post/2025-03-19-r-basic-advanceds-variables-and-names-in-dplyr/index.Rmd index c53de95..04b7dee 100644 --- a/content/post/2025-03-19-r-basic-advanceds-variables-and-names-in-dplyr/index.Rmd +++ b/content/post/2025-03-19-r-basic-advanceds-variables-and-names-in-dplyr/index.Rmd @@ -11,6 +11,7 @@ output: toc: true images: - selection-ambiguity.png + - embracing.png --- ## Intro @@ -120,71 +121,108 @@ my_subset_with_symbols <- function(data, my_var_as_symbol) { my_subset_with_symbols(iris, Petal.Length) -my_subset_with_symbols(iris, Petal.Length, Sepal.Width) +# We still need to wrap column names in a vector if we provide more than one of them for a single parameter +# (or we can use ellipsis operator for the function, but this is a separate design question) +my_subset_with_symbols(iris, c(Petal.Length, Sepal.Width)) ``` In this way we let dplyr know that `my_var_as_symbol` has to be passed directly as user provided it. We can think of embracing as of cut-paste operation. We tell dplyr: "Take what user provided in place of `my_var_as_symbol` in function call and plug it directly into `select`, without creating any intermediate variables.". Call to `my_subset_with_symbols()` is basically replaced with what lies inside of it. +![Diagram showing how the embracing works.](embracing.png) + ## Problem 3: Dynamic columns in purrr formulas in `across` -While the above solutions work seamlessly with functions like `dplyr::select()`, challenges arise when operations grow complex. Suppose we wish to craft a function, `do_magic`, that takes data, a special `column`, and several `others` columns. This function should add the special column to all others. +While the above solutions work seamlessly with functions like `dplyr::select()`, challenges arise when operations grow complex. Suppose we wish to craft a function, `do_magic`, that takes `data`, a special `column`, and several `other` columns. This function should add the special `column` to all `other`. For now, do not assume in what form `column` and `other` parameters are provided. + +The naive way of doing it, would be to construct some `dplyr::mutate()` call that would operate on each of the provided columns: -Leveraging `dplyr::mutate(dplyr::across())` can achieve this. Its syntax is: ```{r eval=FALSE} -mutate(across(columns_to_mutate, function_to_apply)) +# only for illustration purposes, won't actually work: +data %>% + mutate( + other[[1]] = other[[1]] + special, + other[[2]] = other[[2]] + special, + ... + other[[N]] = other[[N]] + special + ) ``` -For custom, unnamed functions, the *purrr formula syntax* (`~ expression` with `.x`) is beneficial. In our case (without enclosing it in a function yet) could look like: -```{r, eval=FALSE} -iris %>% - mutate(across(all_of(c("Sepal.Length", "Sepal.Width")), ~ .x - Petal.Length)) +As you might have known, the code above will not be functional, neither inside or outside function -- you cannot index neither character vector nor symbol on the left side of argument assignment in `dplyr::mutate()` call. We need to use another tool: `dplyr::across()`. Its syntax is: + +```{r eval=FALSE} +data %>% mutate(across(columns_to_mutate, function_to_apply)) +``` + +For custom, unnamed functions, the *function shorthand syntax* `\(x)` is beneficial. The idea from example above could be rewritten as: + +```{r eval=FALSE} +# still won't work, but we are getting somewhere: +data %>% + mutate( + across(other, \(x) + special) + ) ``` -Elegant, isn't it? Now, let's proceed by encapsulating this logic within a function where column names are passed as strings: +Now it is time to actually encapsulate this into a function and think about how to pass those column names as parameters. Since we are already armed with knowledge of previous chapter of this article we might try embracing first: ```{r} -do_magic <- function(data, special, others) { +do_magic <- function(data, special, other) { data %>% - mutate(across(all_of(others), ~ .x - all_of(special))) + mutate(across({{other}}, \(x) + {{special}})) +} + +do_magic(iris, Petal.Length, c(Sepal.Length, Petal.Width)) +``` + +Hooray! It works just fine! However, at this point it is worth trying it out another way and asking question: what if we want to pass those parameters as strings? Again, we can go back to the example from before and use supporting functions to transform the strings into actual selections: + +```{r} +do_magic <- function(data, special, other) { + data %>% + mutate(across(all_of(other), \(x) - all_of(special))) } # won't work: -# do_magic(iris, special = "Petal.Length", others = c("Sepal.Length", "Sepal.Width")) +# do_magic(iris, special = "Petal.Length", other = c("Sepal.Length", "Sepal.Width")) ``` -Surprisingly, it fails! When used within the context of `across`, dplyr seems unable to utilize the tidyselect rules (the ones that make `all_of()` possible). But we're not defeated; let's try embracing: +Surprisingly, it fails! The reason for that is simple: the function we pass into across (in this case: `\(x) - all_of(special)`) is unable to evaluate this selector function as it is unexpected there. Tidyselect rules (the ones that make `all_of()` and its friends possible) are not automagical and require to be invoked manually by the function designer. `dplyr::select` knows that it might expect such expressions but inside some seemingly random function it cannot evaluate properly on its own. + +So, what to do now? We can try mixed approach with embracing: ```{r} -do_magic_but_better <- function(data, special, others) { +do_magic_but_better <- function(data, special, other) { data %>% - mutate(across(all_of(others), ~ .x - {{special}})) + mutate(across(all_of(other), ~ .x - {{special}})) } -do_magic_but_better(iris, special = Petal.Length, others = c("Sepal.Length", "Sepal.Width")) +do_magic_but_better(iris, special = Petal.Length, other = c("Sepal.Length", "Sepal.Width")) ``` -By adopting this approach, it's imperative to provide special as a symbol. Also, this does not look fine: one parameter is provided as symbol, another one is as character vector... **We should always aim at being consistent**. Either all column-like parameters should be symbols or all should be character strings. There are pros and cons to both ways. Let's say that we want to stick to strings only. How can we do it? +This works. How come then that embracing inside anonymous function works while `all_of` helper does not? This is because they use a very different approach and detailed explanation goes out of the scope of this article. To simplify: embracing is a more general approach for replacing one chunk of a code with another provided as a parameter. + +The one issue with above approach is that it does not look fine: one parameter is provided as symbol, another one is as character vector... **We should always aim at being consistent**. Either all column-like parameters should be symbols or all should be character strings. There are pros and cons to both ways. Let's say that we want to stick to strings only. How can we do it? #### Tip: when `all_of()` does not work, use `.data` There's a workaround for this conundrum: ```{r} -do_magic_but_in_other_way <- function(data, special, others) { +do_magic_but_in_other_way <- function(data, special, other) { data %>% - mutate(across(all_of(others), ~ .x - .data[[special]])) + mutate(across(all_of(other), ~ .x - .data[[special]])) } -do_magic_but_in_other_way(iris, special = "Petal.Length", others = c("Sepal.Length", "Sepal.Width")) +do_magic_but_in_other_way(iris, special = "Petal.Length", other = c("Sepal.Length", "Sepal.Width")) ``` -When you need to reference the underlying data within the context of functions, the `.data` pronoun comes to the rescue. As demonstrated, it operates similarly to directly accessing the data. +When you need to reference the underlying data within the context of dplyr functions, the `.data` pronoun comes to the rescue. It is available also from within the function that is evaluated inside `across` helper. As demonstrated, it operates similarly to directly accessing the data and as a result, we can use regular base extraction operator. ## Summary & Next Steps -Throughout this post, we ventured deep into some of the intricacies of dplyr. We've unraveled how the package strives to make our code both semantic and syntactic, all while simplifying complex operations. The power of symbols and the utility of functions like `all_of()` and `.data` demonstrate just how dynamic and adaptable dplyr can be, especially when working with variable column names. While we've covered much ground, the world of dplyr is vast and constantly evolving. We are aware that all this *embracing* and *tidyselect* rules might be intimidating, but we will continue to explore more facets of the tidyverse in future posts of "basic advanceds", aiming to empower you with advanced techniques that enhance your data analysis journey. +Throughout this post, we ventured deep into some of the intricacies of dplyr. We've unraveled how the package strives to make our code both semantic and syntactic, all while simplifying complex operations. The power of symbols and the utility of functions and pronouns like `all_of()` and `.data` demonstrate just how dynamic and adaptable dplyr can be, especially when working with variable column names. While we've covered much ground, the world of dplyr is vast and constantly evolving. We are aware that all this *embracing* and *tidyselect* rules might be intimidating, but we will continue to explore more facets of the tidyverse in future posts of "basic advanceds", aiming to empower you with advanced techniques that enhance your data analysis journey. If you've found this post enlightening and wish to delve deeper, or if you have any questions or insights, we'd love to hear from you! You can contact us directly via [X](https://twitter.com/Rturtletopia). Alternatively, for those who prefer a more open-source avenue, feel free to open an issue on our [GitHub](https://github.com/turtletopia/turtletopia.github.io/issues) repository. Your feedback and insights not only help us improve, but they also contribute to the broader data science community. @@ -192,4 +230,4 @@ Until next time, keep exploring, learning, and sharing! ## Dive Deeper: Resources for the Curious Minds: -For those wishing to delve further or who may have lingering questions: [dplyr official programming guide](https://dplyr.tidyverse.org/articles/programming.html) +For those wishing to delve further or who may have lingering questions a great resource would be [dplyr official programming guide](https://dplyr.tidyverse.org/articles/programming.html). If this is still not enough for you, we recommend a few chapters of [Advanced R book](https://adv-r.hadley.nz/metaprogramming.html) that focus on metaprogramming and underlying tools used to build tidyverse. diff --git a/content/post/2025-03-19-r-basic-advanceds-variables-and-names-in-dplyr/index.html b/content/post/2025-03-19-r-basic-advanceds-variables-and-names-in-dplyr/index.html index 024af44..b95e6a7 100644 --- a/content/post/2025-03-19-r-basic-advanceds-variables-and-names-in-dplyr/index.html +++ b/content/post/2025-03-19-r-basic-advanceds-variables-and-names-in-dplyr/index.html @@ -11,6 +11,7 @@ toc: true images: - selection-ambiguity.png + - embracing.png --- @@ -117,64 +118,97 @@

    Problem 2: Passing column names as arguments to custom functions

    my_subset_with_symbols(iris, Petal.Length) -my_subset_with_symbols(iris, Petal.Length, Sepal.Width) +# We still need to wrap column names in a vector if we provide more than one of them for a single parameter +# (or we can use ellipsis operator for the function, but this is a separate design question) +my_subset_with_symbols(iris, c(Petal.Length, Sepal.Width))

    In this way we let dplyr know that my_var_as_symbol has to be passed directly as user provided it. We can think of embracing as of cut-paste operation. We tell dplyr: “Take what user provided in place of my_var_as_symbol in function call and plug it directly into select, without creating any intermediate variables.”. Call to my_subset_with_symbols() is basically replaced with what lies inside of it.

    +
    +Diagram showing how the embracing works. +
    Diagram showing how the embracing works.
    +

    Problem 3: Dynamic columns in purrr formulas in across

    -

    While the above solutions work seamlessly with functions like dplyr::select(), challenges arise when operations grow complex. Suppose we wish to craft a function, do_magic, that takes data, a special column, and several others columns. This function should add the special column to all others.

    -

    Leveraging dplyr::mutate(dplyr::across()) can achieve this. Its syntax is:

    -
    mutate(across(columns_to_mutate, function_to_apply))
    -

    For custom, unnamed functions, the purrr formula syntax (~ expression with .x) is beneficial. In our case (without enclosing it in a function yet) could look like:

    -
    iris %>%
    -  mutate(across(all_of(c("Sepal.Length", "Sepal.Width")), ~ .x - Petal.Length))
    -

    Elegant, isn’t it? Now, let’s proceed by encapsulating this logic within a function where column names are passed as strings:

    -
    do_magic <- function(data, special, others) {
    +

    While the above solutions work seamlessly with functions like dplyr::select(), challenges arise when operations grow complex. Suppose we wish to craft a function, do_magic, that takes data, a special column, and several other columns. This function should add the special column to all other. For now, do not assume in what form column and other parameters are provided.

    +

    The naive way of doing it, would be to construct some dplyr::mutate() call that would operate on each of the provided columns:

    +
    # only for illustration purposes, won't actually work:
    +data %>%
    +  mutate(
    +    other[[1]] = other[[1]] + special,
    +    other[[2]] = other[[2]] + special,
    +    ...
    +    other[[N]] = other[[N]] + special
    +  )
    +

    As you might have known, the code above will not be functional, neither inside or outside function – you cannot index neither character vector nor symbol on the left side of argument assignment in dplyr::mutate() call. We need to use another tool: dplyr::across(). Its syntax is:

    +
    data %>% mutate(across(columns_to_mutate, function_to_apply))
    +

    For custom, unnamed functions, the function shorthand syntax \(x) is beneficial. The idea from example above could be rewritten as:

    +
    # still won't work, but we are getting somewhere:
    +data %>%
    +  mutate(
    +    across(other, \(x) + special)
    +  )
    +

    Now it is time to actually encapsulate this into a function and think about how to pass those column names as parameters. Since we are already armed with knowledge of previous chapter of this article we might try embracing first:

    +
    do_magic <- function(data, special, other) {
    +  data %>%
    +    mutate(across({{other}}, \(x) + {{special}}))
    +} 
    +
    +do_magic(iris, Petal.Length, c(Sepal.Length, Petal.Width))
    +
    ##   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
    +## 1          1.4         3.5          1.4         1.4  setosa
    +## 2          1.4         3.0          1.4         1.4  setosa
    +## 3          1.3         3.2          1.3         1.3  setosa
    +## 4          1.5         3.1          1.5         1.5  setosa
    +## 5          1.4         3.6          1.4         1.4  setosa
    +

    Hooray! It works just fine! However, at this point it is worth trying it out another way and asking question: what if we want to pass those parameters as strings? Again, we can go back to the example from before and use supporting functions to transform the strings into actual selections:

    +
    do_magic <- function(data, special, other) {
       data %>%
    -    mutate(across(all_of(others), ~ .x - all_of(special)))
    +    mutate(across(all_of(other), \(x) - all_of(special)))
     }
     
     # won't work:
    -# do_magic(iris, special = "Petal.Length", others = c("Sepal.Length", "Sepal.Width"))
    -

    Surprisingly, it fails! When used within the context of across, dplyr seems unable to utilize the tidyselect rules (the ones that make all_of() possible). But we’re not defeated; let’s try embracing:

    -
    do_magic_but_better <- function(data, special, others) {
    +# do_magic(iris, special = "Petal.Length", other = c("Sepal.Length", "Sepal.Width"))
    +

    Surprisingly, it fails! The reason for that is simple: the function we pass into across (in this case: \(x) - all_of(special)) is unable to evaluate this selector function as it is unexpected there. Tidyselect rules (the ones that make all_of() and its friends possible) are not automagical and require to be invoked manually by the function designer. dplyr::select knows that it might expect such expressions but inside some seemingly random function it cannot evaluate properly on its own.

    +

    So, what to do now? We can try mixed approach with embracing:

    +
    do_magic_but_better <- function(data, special, other) {
       data %>%
    -    mutate(across(all_of(others), ~ .x - {{special}}))
    +    mutate(across(all_of(other), ~ .x - {{special}}))
     }
     
    -do_magic_but_better(iris, special = Petal.Length, others = c("Sepal.Length", "Sepal.Width"))
    +do_magic_but_better(iris, special = Petal.Length, other = c("Sepal.Length", "Sepal.Width"))
    ##   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
     ## 1          3.7         2.1          1.4         0.2  setosa
     ## 2          3.5         1.6          1.4         0.2  setosa
     ## 3          3.4         1.9          1.3         0.2  setosa
     ## 4          3.1         1.6          1.5         0.2  setosa
     ## 5          3.6         2.2          1.4         0.2  setosa
    -

    By adopting this approach, it’s imperative to provide special as a symbol. Also, this does not look fine: one parameter is provided as symbol, another one is as character vector… We should always aim at being consistent. Either all column-like parameters should be symbols or all should be character strings. There are pros and cons to both ways. Let’s say that we want to stick to strings only. How can we do it?

    +

    This works. How come then that embracing inside anonymous function works while all_of helper does not? This is because they use a very different approach and detailed explanation goes out of the scope of this article. To simplify: embracing is a more general approach for replacing one chunk of a code with another provided as a parameter.

    +

    The one issue with above approach is that it does not look fine: one parameter is provided as symbol, another one is as character vector… We should always aim at being consistent. Either all column-like parameters should be symbols or all should be character strings. There are pros and cons to both ways. Let’s say that we want to stick to strings only. How can we do it?

    Tip: when all_of() does not work, use .data

    There’s a workaround for this conundrum:

    -
    do_magic_but_in_other_way <- function(data, special, others) {
    +
    do_magic_but_in_other_way <- function(data, special, other) {
       data %>%
    -    mutate(across(all_of(others), ~ .x - .data[[special]]))
    +    mutate(across(all_of(other), ~ .x - .data[[special]]))
     }
     
    -do_magic_but_in_other_way(iris, special = "Petal.Length", others = c("Sepal.Length", "Sepal.Width"))
    +do_magic_but_in_other_way(iris, special = "Petal.Length", other = c("Sepal.Length", "Sepal.Width"))
    ##   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
     ## 1          3.7         2.1          1.4         0.2  setosa
     ## 2          3.5         1.6          1.4         0.2  setosa
     ## 3          3.4         1.9          1.3         0.2  setosa
     ## 4          3.1         1.6          1.5         0.2  setosa
     ## 5          3.6         2.2          1.4         0.2  setosa
    -

    When you need to reference the underlying data within the context of functions, the .data pronoun comes to the rescue. As demonstrated, it operates similarly to directly accessing the data.

    +

    When you need to reference the underlying data within the context of dplyr functions, the .data pronoun comes to the rescue. It is available also from within the function that is evaluated inside across helper. As demonstrated, it operates similarly to directly accessing the data and as a result, we can use regular base extraction operator.

    Summary & Next Steps

    -

    Throughout this post, we ventured deep into some of the intricacies of dplyr. We’ve unraveled how the package strives to make our code both semantic and syntactic, all while simplifying complex operations. The power of symbols and the utility of functions like all_of() and .data demonstrate just how dynamic and adaptable dplyr can be, especially when working with variable column names. While we’ve covered much ground, the world of dplyr is vast and constantly evolving. We are aware that all this embracing and tidyselect rules might be intimidating, but we will continue to explore more facets of the tidyverse in future posts of “basic advanceds”, aiming to empower you with advanced techniques that enhance your data analysis journey.

    +

    Throughout this post, we ventured deep into some of the intricacies of dplyr. We’ve unraveled how the package strives to make our code both semantic and syntactic, all while simplifying complex operations. The power of symbols and the utility of functions and pronouns like all_of() and .data demonstrate just how dynamic and adaptable dplyr can be, especially when working with variable column names. While we’ve covered much ground, the world of dplyr is vast and constantly evolving. We are aware that all this embracing and tidyselect rules might be intimidating, but we will continue to explore more facets of the tidyverse in future posts of “basic advanceds”, aiming to empower you with advanced techniques that enhance your data analysis journey.

    If you’ve found this post enlightening and wish to delve deeper, or if you have any questions or insights, we’d love to hear from you! You can contact us directly via X. Alternatively, for those who prefer a more open-source avenue, feel free to open an issue on our GitHub repository. Your feedback and insights not only help us improve, but they also contribute to the broader data science community.

    Until next time, keep exploring, learning, and sharing!

    Dive Deeper: Resources for the Curious Minds:

    -

    For those wishing to delve further or who may have lingering questions: dplyr official programming guide

    +

    For those wishing to delve further or who may have lingering questions a great resource would be dplyr official programming guide. If this is still not enough for you, we recommend a few chapters of Advanced R book that focus on metaprogramming and underlying tools used to build tidyverse.

    diff --git a/content/post/2025-03-19-r-basic-advanceds-variables-and-names-in-dplyr/images/selection-ambiguity.png b/content/post/2025-03-19-r-basic-advanceds-variables-and-names-in-dplyr/selection-ambiguity.png similarity index 100% rename from content/post/2025-03-19-r-basic-advanceds-variables-and-names-in-dplyr/images/selection-ambiguity.png rename to content/post/2025-03-19-r-basic-advanceds-variables-and-names-in-dplyr/selection-ambiguity.png diff --git a/content/post/2025-03-19-r-basic-advanceds-variables-and-names-in-dplyr/images/selection-ambiguity.svg b/content/post/2025-03-19-r-basic-advanceds-variables-and-names-in-dplyr/selection-ambiguity.svg similarity index 100% rename from content/post/2025-03-19-r-basic-advanceds-variables-and-names-in-dplyr/images/selection-ambiguity.svg rename to content/post/2025-03-19-r-basic-advanceds-variables-and-names-in-dplyr/selection-ambiguity.svg