1

Apologies in advance, I'm struggling with how to phrase this question and I hope my repex is sufficiently explanatory.

I'm trying to use a combination of 's mutate_ and anonymous functions to apply a transformation to a variable with the goal of returning the original variable and its transformed counter part to the data frame. I'm struggling on how to rename the output the function returns, while keeping the original. So far it only returns the modified copy of the original.

So far, my code takes the original inputs, and returns their transformed versions to the data such as in the current_output object. I tried to use assign() nested in return() to allow for more flexible naming and to return a new variable all together like in the desired_output object but no such luck.

library(tidyverse)

data <- data.frame(X1 = c(2, 2, 2, 2),
                   X1a = c(3, 3, 3, 3),
                   X2 = c(3, 3, 3, 3))

data%>%
  mutate_at(vars(X1,
                 X1a),
            function(x){ 
              X2 = get("X2", parent.frame())
              X1a = x * X2
              return(assign(paste(x, "X2", "_Product", sep = "_"), X1a))
            }) -> data2

desired_output <- data.frame(X1 = c(2, 2, 2, 2),
                           X1a = c(3, ,3 , 3),
                           X2 = c(3, 3, 3, 3),
                           X1_X2_Product = c(6, 6, 6, 6),
                           X1a_X2_Product = c(9, 9, 9, 9))

current_output <- data.frame(X1 = c(6, 6, 6, 6),
                             X1a = c(9, 9, 9, 9),
                             X2 = c(3, 3, 3, 3))
2
  • 2
    data %>% mutate(across(starts_with("X1"), ~ .x * X2, .names = "{.col}_X2_Product")). Don't use mutate_at() - it's been retired in favor of across(). Commented Mar 29, 2022 at 23:05
  • 1
    data %>% mutate_at(vars(X1, X1a), list(X2_product = ~.x * X2)) or data %>% mutate(across(c(X1, X1a), list(X2_product = ~.x * X2))) Commented Mar 29, 2022 at 23:06

2 Answers 2

2

We could use across and its .names argument:

library(dplyr)
data %>% 
  mutate(across(c(X1, X1a), ~ .x* X2, .names = "{.col}_X2_Product"))
  X1 X1a X2 X1_X2_Product X1a_X2_Product
1  2   3  3             6              9
2  2   3  3             6              9
3  2   3  3             6              9
4  2   3  3             6              9
Sign up to request clarification or add additional context in comments.

Comments

1

This answer does not respect all the constraints required by the question, but is here for comedic effect:

library(base)  # I know...

data$X1_X2_Product  <- data$X1  * data$X2
data$X1a_X2_Product <- data$X1a * data$X2

2 Comments

I know this will work but in the data Im working on I have to apply this transformation to about 50 or so variables. Im working off the "if you copy it more than three times it should be a function" rule.
@Araph7 I understand, sure. The comedic effect I was counting on is about how impenetrable the tidyverse code is, compared to the basic operations on a plain data.frame.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.