Dplyr 0.7 Equivalent for Deprecated Mutate_

dplyr 0.7 equivalent for deprecated mutate_

To expand a little bit on MrFlick's example, let's assume you have a number of instructions stored as strings, as well as the corresponding names that you want to assign to the resulting computations:

ln <- list( "test2", "test3" )
lf <- list( "substr(test, 1, 5)", "substr(test, 5, 5)" )

Match up names to their instructions and convert everything to quosures:

ll <- setNames( lf, ln ) %>% lapply( rlang::parse_quosure )

As per aosmith's suggestion, the entire list can now be passed to mutate, using the special !!! operator:

tibble( test = "test@test" ) %>% mutate( !!! ll )
# # A tibble: 1 x 3
# test test2 test3
# <chr> <chr> <chr>
# 1 test@test test@ @

Equivalent for deprecated select_() and mutate_()

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")

mutate_ deprecated, easy and understandable alternatives?

You can use {{ }} (curly curly). See Tidy evaluation section in Hadley Wickham's Advanced R book. Below is an example using the gapminder dataset.

library(gapminder)
library(rlang)
library(tidyverse)

Add_Extreme_Variable2 <- function(dataframe, group_by_var1, group_by_var2, variable, variable_name) {
res <- dataframe %>%
group_by({{group_by_var1}}, {{group_by_var2}}) %>%
mutate({{variable_name}} := ifelse({{variable}} > quantile({{variable}}, 0.95, na.rm = TRUE), 1, 0)) %>%
ungroup()
return(res)
}

df <- Add_Extreme_Variable2(gapminder, continent, year, pop, pop_extreme) %>%
arrange(desc(pop_extreme))
df
#> # A tibble: 1,704 x 7
#> country continent year lifeExp pop gdpPercap pop_extreme
#> <fct> <fct> <int> <dbl> <int> <dbl> <dbl>
#> 1 Australia Oceania 1952 69.1 8691212 10040. 1
#> 2 Australia Oceania 1957 70.3 9712569 10950. 1
#> 3 Australia Oceania 1962 70.9 10794968 12217. 1
#> 4 Australia Oceania 1967 71.1 11872264 14526. 1
#> 5 Australia Oceania 1972 71.9 13177000 16789. 1
#> 6 Australia Oceania 1977 73.5 14074100 18334. 1
#> 7 Australia Oceania 1982 74.7 15184200 19477. 1
#> 8 Australia Oceania 1987 76.3 16257249 21889. 1
#> 9 Australia Oceania 1992 77.6 17481977 23425. 1
#> 10 Australia Oceania 1997 78.8 18565243 26998. 1
#> # ... with 1,694 more rows

summary(df)
#> country continent year lifeExp
#> Afghanistan: 12 Africa :624 Min. :1952 Min. :23.60
#> Albania : 12 Americas:300 1st Qu.:1966 1st Qu.:48.20
#> Algeria : 12 Asia :396 Median :1980 Median :60.71
#> Angola : 12 Europe :360 Mean :1980 Mean :59.47
#> Argentina : 12 Oceania : 24 3rd Qu.:1993 3rd Qu.:70.85
#> Australia : 12 Max. :2007 Max. :82.60
#> (Other) :1632
#> pop gdpPercap pop_extreme
#> Min. :6.001e+04 Min. : 241.2 Min. :0.00000
#> 1st Qu.:2.794e+06 1st Qu.: 1202.1 1st Qu.:0.00000
#> Median :7.024e+06 Median : 3531.8 Median :0.00000
#> Mean :2.960e+07 Mean : 7215.3 Mean :0.07042
#> 3rd Qu.:1.959e+07 3rd Qu.: 9325.5 3rd Qu.:0.00000
#> Max. :1.319e+09 Max. :113523.1 Max. :1.00000
#>

Created on 2019-11-10 by the reprex package (v0.3.0)

What is the alternative to deprecated SE dplyr verbs in a for loop?

Use sym to turn the string into a symbol, then use !! to insert the symbol into the expression

for (i in names(df %>% select(x,z))){
print(count(df, !!sym(i)))
}

How to replace mutate_ with mutate when using a series to replace swap columns?

There are easier ways to do this (see Ronak Shah's base R approach, for example), however since you specifically asked about how to switch from mutate_ to mutate, you can adjust your original code in this way:

swapThem <- function(to, from) {

cols <- colnames(from)

if (length(cols) != 0) {

# Loop through `from` columns and if there's a match in `to`, copy and paste
# it into `to`
for (i in seq_along(cols)) {
col <- cols[i]
if (col %in% colnames(to)) {
to <- to %>% dplyr::mutate(!!sym(col) := from[[col]])
} else {
next
}
}
}
return(to)
}

Note that you can also use {{}}, like this:

to <- to %>% dplyr::mutate({{col}} := from[[col]])

Here is another tidy approach, that uses bind_cols. The relocate is to ensure that the order of columns in to is preserved

swapThem <- function(to,from) {
bind_cols(
to %>% select(all_of(setdiff(colnames(to), colnames(from)))),
from %>% select(all_of(intersect(colnames(to), colnames(from))))
) %>%
relocate(colnames(to))
}

Using quotations inside mutate: an alternative to mutate_(.dots = ...)

Convert your strings to expressions

myexprs <- purrr::map( myfuns, rlang::parse_expr )

then pass those expressions to regular mutate using quasiquotation:

tibble(a = 1:3) %>% mutate( !!!myexprs )
# # A tibble: 3 x 4
# a f1 f2 f3
# <int> <dbl> <dbl> <dbl>
# 1 1 1 2.72 1
# 2 2 4 7.39 1.41
# 3 3 9 20.1 1.73

Note that this will also work with strings / expressions involving multiple columns.

How to remove warning message about funs() is deprecated in dplyr

across is the current way to summarize/mutate multiple columns (since dplyr version 1.0). And we also use purrr-style anonymous functions with ~.

iris %>% count(Species) %>%
bind_rows(summarize(., across(everything(), ~if(is.numeric(.)) sum(.) else "Total")))
# Species n
# 1 setosa 50
# 2 versicolor 50
# 3 virginica 50
# 4 Total 150

dplyr summarize across ttest

If we are using tidy

library(dplyr)
library(broom)
library(tidyr)
mtcars %>%
group_by(am) %>%
summarise(across(
.cols = mpg,
~ list(tidy(t.test(.[vs == 0], .[vs == 1])) %>%
select(p.value, conf.low, conf.high))
)) %>%
unnest(mpg)

-output

# A tibble: 2 x 4
am p.value conf.low conf.high
<dbl> <dbl> <dbl> <dbl>
1 0 0.000395 -8.33 -3.05
2 1 0.00459 -14.0 -3.27

In the OP's code, we need the lambda function inside the list

mtcars  %>%
group_by(am) %>%
summarise(across(
.cols = mpg,
.fns = list(
p.value = ~ t.test(.[vs == 0], .[vs == 1])$p.value,
conf.low = ~ t.test(.[vs == 0], .[vs == 1])$conf.int[1],
conf.high =~ t.test(.[vs == 0], .[vs == 1])$conf.int[2]
)
))

-output

# A tibble: 2 x 4
am mpg_p.value mpg_conf.low mpg_conf.high
<dbl> <dbl> <dbl> <dbl>
1 0 0.000395 -8.33 -3.05
2 1 0.00459 -14.0 -3.27

dplyr 0.5.0 mutate using column index

The new prototype of mutate_at is:

mutate_at(.tbl, .vars, .funs, ..., .cols = NULL)

Notice, that the .vars is the first argument now. So, either you specify .vars explicitly or change the order.

newdata <- data %>% mutate_at(funs(change), .vars = vars(1:2))
# OR
newdata <- data %>% mutate_at(vars(1:2), funs(change))

numbers morenumbers
1 2 1
2 2 1
3 2 1
4 2 1
5 2 1
6 2 1
7 2 1
8 2 1
9 2 1
10 2 1


Related Topics



Leave a reply



Submit