Home > database >  Mutating columns with reduce2 and rlang
Mutating columns with reduce2 and rlang

Time:05-20

I am trying the following:

library(tidyverse)
library(rlang)

df <- data.frame(a = 1:2)

reduce2(list(df, df, df), letters[2:3], ~ mutate(.x, !!(.y) := 2:3))
#> Error in local_error_context(dots = dots, .index = i, mask = mask): promise already under evaluation: recursive default argument reference or earlier problems?

I do know many ways of mutating columns to a dataframe, but I am trying to learn rlang.

The expected output:

  a b c
1 1 2 2
2 2 3 3

CodePudding user response:

A method to combine purrr::reduce() and rlang is:

library(dplyr)
library(purrr)

reduce(letters[2:3], ~ .x %>% mutate(!!.y := 2:3), .init = df)

#   a b c
# 1 1 2 2
# 2 2 3 3

where the trick is to assign df to the argument .init.

CodePudding user response:

I don't think reduce2 is the correct function here, since you aren't actually using any items an the list of data frames after the first iteration. The function that is passed to reduce2 takes three arguments - the first is the object being reduced, the second is the next item in .x and the third being the next item in .y.

That means you can still use reduce2 if you want, by doing:

reduce2(.x = list(df, df, df), .y = letters[2:3], 
        .f = function(A, B, C) mutate(A, {{C}} := 2:3))
#>   a b c
#> 1 1 2 2
#> 2 2 3 3

But note that you are not using the second argument in the function body. You could do it just with reduce:

reduce(list(df, 'b', 'c'), ~ mutate(.x, !!.y := 2:3))

CodePudding user response:

I am sure you are aware that you can do df[letters[2:3]] <- 2:3 to achieve the same output but I don't think this is what you are looking for.

To use purrr and rlang you may use -

library(dplyr)
library(purrr)

bind_cols(df, map_dfc(letters[2:3], ~df %>% transmute(!!.x := 2:3)))

#  a b c
#1 1 2 2
#2 2 3 3

And another way would be -

map(letters[2:3], ~df %>% mutate(!!.x := 2:3)) %>% reduce(inner_join, by = 'a')
  • Related