Dynamic Sorting

We wish to specify the sorting columns dynamically i.e. through a variable or a function argument. In particular, we cover the following scenarios:

  • As Function Argument: We wish to pass the sorting columns to a function where the sorting will be carried out.
  • As String Variable: The names of the column that we wish to sort by are available as string variables.

In this section we cover the specification of sorting column names dynamically. For more involved dynamic sorting scenarios:

  • If you wish to dynamically specify the function to use to select the sorting columns, see Dynamic Selection for how to specify an implicit column selection function dynamically.
  • If you wish to dynamically specify the function to use to apply to the sorting columns before sorting, see Dynamic Transformation for how to specify a transformation function dynamically.

As Function Argument

One Column

We wish to pass one sorting column to a function wherein sorting takes place.

m_arrange <- function(.df, var) {  
  .df %>%    
    arrange({{ var }})
}

df %>% m_arrange(desc(col_1))

Here is how this works:

  • We have a custom function m_arrange() to which we pass the data frame to be sorted (which is here df) and the column to sort by (which is here col_1)
  • We use the {{ }} operator to "tunnel" a data variable through a function argument.
  • We can wrap the column name in desc() to sort in descending order like we did here with desc(col_1).

N Columns

We wish to pass a fixed number of sorting columns to a function wherein sorting takes place.

In this example, we wish to pass two columns to a custom function where sorting takes place.

m_arrange <- function(.df, var_1, var_2) {  
  .df %>%    
    arrange({{ var_1 }}, {{ var_2 }})
}

df %>% m_arrange(col_1, desc(col_2))

Here is how this works:

  • This works similarly to the “One Column” scenario except that we pass N columns where N here is 2.
  • We use the {{ }} operator to "tunnel" each of the data variables through their respective function argument.
  • We can choose to wrap a variable in desc() to have it be sorted in descending order.

Multiple Columns

We wish to pass an arbitrary number of sorting columns (i.e. the number of sorting columns is not known in advance) to a function wherein sorting takes place.

m_arrange <-function(.data, vars){
  .data %>%    
    arrange(across({{ vars }}))
}

df %>%
  m_arrange(c(col_1, col_2, col_3))

Here is how this works:

  • We use the {{ }} operator to "tunnel" a list of variables through a function argument to across().
  • Note that in this case we are sorting in ascending order of all sorting columns.
    • We can pass desc to the second argument of across to sort in descending order of all columns.
    • In order to sort in descending order of some or all columns, we would need to write a custom function that we pass to the second argument of across and use cur_column() in that function to apply desc to the appropriate columns.

As String Variable

The names of the column that we wish to sort by are specified as strings in an environment variables (or a function argument).

One Column

col = 'col_1'

df %>%
  arrange(across({{ col }}, desc))

Here is how this works:

  • We use the {{ }} operator to "tunnel" a string variable. {{ }} is used when we want a variable to be substituted in place before being evaluated.
  • across() can take a function as its second argument. To sort in descending order, we can pass desc to the second argument of across().

Multiple Columns

cols = c('col_1', 'col_2', 'col_3')

df %>%
  arrange(across({{ cols }}))

Here is how this works:

  • We use the {{ }} operator to "tunnel" a vector of strings stored in a variable (here cols). {{ }} is used when we want a variable to be substituted in place before being evaluated.
  • Note that in this case we are sorting in ascending order of all sorting columns. We can pass
  • Note that in this case we are sorting in ascending order of all sorting columns.
    • We can pass desc to the second argument of across to sort in descending order of all columns.
    • In order to sort in descending order of some or all columns, we would need to write a custom function that we pass to the second argument of across and use cur_column() in that function to apply desc to the appropriate columns.
R
I/O