Equivalent for deprecated select_() and mutate_()

Viewed 565

Equivalent for deprecated select_() and mutate_()

I am trying to make a function with this data and would really appreciate your help!

Imagine I have a data.frame like this one (the fusion of control and sites).

I want to select the InitDryW and FinalDryW columns of the Treatment “Control” and then calculate the average. Inside the function I must write select_() and then mutate_(). However, I understand that these two functions are deprecated.

control <- data.frame(Day=c(0,0,0,0,0,0),
              Replica=c(1,1,1,1,1,1),
              Initial_Dry_Weight=c(5.010,5.010,5.010,5.010,5.010,5.000),
              Final_Dry_Weight=c(4.990,4.940,4.840,4.820,4.960,4.970),
              InitiaFraction=c(1.1071,1.1964,1.0647,1.0005,1.0453,1.1212),
              FinalFraction=c(0.3858,0.3504,0.4248,0.3333,0.3417,0.3467),
              Treatment=c("Control","Control","Control","Control","Control","Control"))
control
sites <-data.frame(Day=c(2,4,8,16,32,44),
               Replica=c(1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3),
               Initial_Dry_Weight=c(5.000,5.000,5.000,5.000,5.01,5.000,5.000,5.000,
                                    5.000,5.000,5.000,5.01,5.01,5.01,5.000,5.000,5.000,5.000),
               Final_Dry_Weight=c(4.65,4.63,4.67,4.64,4.37,4.37,4.17,3.72,4.12,4,3.99,3.64,
                                  4.26,3.3,3.47,3.7,3.75,3.3),
            InitiaFraction=c(1.0081,1.0972,1.1307,1.0898,1.075,1.0295,1.0956,1.042,1.0876,
             1.006,1.1052,1.0922,1.0472,1.0843,1.0177,1.0143,1.1112,1.0061),
            FinalFraction=c(0.3229,0.3605,0.3304,0.3489,0.3181,0.2948,0.4098,0.3762,0.3787,
            0.3345,0.3595,0.3511,0.3921,0.3908,0.3385,0.347,0.3366,0.3318),
            Treatment=c("CC","CC","CC","CC","CC","CC","CC","CC","CC","CC","CC","CC","CC",
                "CC","CC","CC","CC","CC"))
sites
total <- dplyr::bind_rows(control,sites)
total

My functions is:

manipulation <- function(data,
                     InitDryW,
                     FinalDryW,
                     Treatment,
                     Difference) {control <- data %>% 
filter(Treatment == "Control") %>%
select_(InitDryW,FinalDryW) %>%
mutate_(Difference = lazyeval::interp (~a/b,  a=as.name(FinalDryW),b=as.name(InitDryW)))
meanControl <- mean(control$Difference, na.rm = TRUE)
return (meanControl)
}
manipulation()

Then, I run the example:

control <- manipulation(data= total,
                    InitDryW = "Initial_Dry_Weight",
                    FinalDryW = "Final_Dry_Weight",
                    Treatment = "Treatment")
control

Now, I'm getting warnings like these (for both select_() and mutate_()):

Warning message: mutate_() is deprecated. Please use mutate() instead The 'programming' vignette or the tidyeval book can help you to program with mutate() : https://tidyeval.tidyverse.org

The result is correct, but the first time that warning appears.

My question is: what is the equivalent of select_() and mutate_() in functions in this case?

I think now select_() is solved using only select()

Thanks in advance!!!

2 Answers

You can pass unqouted column names and use {{}} to evaluate it.

library(dplyr)
library(rlang)

manipulation <- function(data,InitDryW,FinalDryW,Treatment,Difference) {
   control <- data %>% 
               filter({{Treatment}} == "Control") %>%
               select({{InitDryW}},{{FinalDryW}}) %>%
               mutate(Difference = {{FinalDryW}}/{{InitDryW}})
                 
    meanControl <- mean(control$Difference, na.rm = TRUE)
    return (meanControl)
}


manipulation(data= total,
             InitDryW = Initial_Dry_Weight,
             FinalDryW = Final_Dry_Weight,
             Treatment = Treatment)

However, based on @27 ϕ 9's comment we think you might want to do :

manipulation <- function(data,InitDryW,FinalDryW,Treatment) {
   control <- data %>% 
               filter(Treatment == Treatment) %>%
               select({{InitDryW}},{{FinalDryW}}) %>%
               mutate(Difference = {{FinalDryW}}/{{InitDryW}})

    meanControl <- mean(control$Difference, na.rm = TRUE)
    return (meanControl)
}


manipulation(data= total,
             InitDryW = Initial_Dry_Weight,
             FinalDryW = Final_Dry_Weight,
             Treatment = "Control")

I think NSE (non standard evaluation) could help you. At first it might be a little bit confusing, but I think it's quite an elegant way to forget about the underscore functions :) All(?) the dplyr functions work somehow that way. So you should already be familiar with the concept (even if you didn't know about it):

... here is an example.

# some data
dat <- dplyr::tibble(A=1:5,
                     B=5:1)
# some function
some_function <- function(dat,     
                          .var){   
  .var <- rlang::enquo(.var)
  dat %>%
    dplyr::select(!!.var)
}

# run function
some_function(dat,.var=B)

# output
# A tibble: 5 x 1
B
<int>
1     5
2     4
3     3
4     2
5     1
Related