Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Moving from mutate_all to across() in dplyr 1.0

Tags:

r

dplyr

With the new release of dplyr I am refactoring quite a lot of code and removing functions that are now retired or deprecated. I had a function that is as follows:

processingAggregatedLoad <- function (df) {
  defined <- ls()
  passed <- names(as.list(match.call())[-1])
  
  if (any(!defined %in% passed)) {
    stop(paste("Missing values for the following arguments:", paste(setdiff(defined, passed), collapse=", ")))
  }
  
  df_isolated_load <- df %>% select(matches("snsr_val")) %>% mutate(global_demand = rowSums(.)) # we get isolated load
  df_isolated_load_qlty <- df %>% select(matches("qlty_good_ind")) # we get isolated quality
  df_isolated_load_qlty <- df_isolated_load_qlty %>% mutate_all(~ factor(.), colnames(df_isolated_load_qlty)) %>%
  mutate_each(funs(as.numeric(.)), colnames(df_isolated_load_qlty)) # we convert the qlty to factors and then to numeric
  df_isolated_load_qlty[df_isolated_load_qlty[]==1] <- 1  # 1 is bad
  df_isolated_load_qlty[df_isolated_load_qlty[]==2] <- 0 # 0 is good we mask to calculate the global index quality
  df_isolated_load_qlty <- df_isolated_load_qlty %>% mutate(global_quality = rowSums(.)) %>% select(global_quality)
  df <- bind_cols(df, df_isolated_load, df_isolated_load_qlty)
  return(df)
}

Basically the function does as follows:

1.The function selects all of the values of a pivoted dataframe and aggregated them.

2.The function selects the quality indicator (character) of a pivoted dataframe.

3.I convert the characters of the quality to factors and then to numeric to get the 2 levels (1 or 2).

4.I replace the numeric values of each of the individual columns by 0 or 1 depending on the level.

5.I rowsum the individual quality as I will get 0 if all of the values are good, otherwise the global quality is bad.

The problem is that I am getting the following messages:

1: `funs()` is deprecated as of dplyr 0.8.0.
Please use a list of either functions or lambdas: 

  # Simple named list: 
  list(mean = mean, median = median)

  # Auto named with `tibble::lst()`: 
  tibble::lst(mean, median)

  # Using lambdas
  list(~ mean(., trim = .2), ~ median(., na.rm = TRUE))
This warning is displayed once every 8 hours.
Call `lifecycle::last_warnings()` to see where this warning was generated. 
2: `mutate_each_()` is deprecated as of dplyr 0.7.0.
Please use `across()` instead.

I did multiple trials as for instance:

 df_isolated_load_qlty %>% mutate(across(.fns = ~ as.factor(), .names = colnames(df_isolated_load_qlty)))
Error: Problem with `mutate()` input `..1`.
x All unnamed arguments must be length 1
ℹ Input `..1` is `across(.fns = ~as.factor(), .names = colnames(df_isolated_load_qlty))`.

But I am still a bit confused about the new dplyr syntax. Would someone be able to guide me a little bit around the right way of doing this?

like image 890
tfkLSTM Avatar asked Nov 02 '25 06:11

tfkLSTM


1 Answers

  • mutate_each has been long deprecated and was replaced with mutate_all.
  • mutate_all is now replaced with across
  • across has default .cols as everything() which means it behaves as mutate_all by default (like here) if not mentioned explicitly.
  • You can apply the mulitple function in the same mutate call, so here factor and as.numeric can be applied together.

Considering all this you can change your existing function to :

library(dplyr)

processingAggregatedLoad <- function (df) {
      defined <- ls()
      passed <- names(as.list(match.call())[-1])

     if (any(!defined %in% passed)) {
            stop(paste("Missing values for the following arguments:", 
             paste(setdiff(defined, passed), collapse=", ")))
      }

     df_isolated_load <- df %>% 
                          select(matches("snsr_val")) %>% 
                          mutate(global_demand = rowSums(.))
    df_isolated_load_qlty <- df %>% select(matches("qlty_good_ind"))
    df_isolated_load_qlty <- df_isolated_load_qlty %>% 
                               mutate(across(.fns = ~as.numeric(factor(.))))
                          
    df_isolated_load_qlty[df_isolated_load_qlty ==1] <- 1  
    df_isolated_load_qlty[df_isolated_load_qlty==2] <- 0
    df_isolated_load_qlty <- df_isolated_load_qlty %>% 
                               mutate(global_quality = rowSums(.)) %>% 
                               select(global_quality)
    df <- bind_cols(df, df_isolated_load, df_isolated_load_qlty)
    return(df)
  }
like image 161
Ronak Shah Avatar answered Nov 04 '25 20:11

Ronak Shah