1
votes

I am trying to run a function of the following structure:

my_fun <- function(new_var_names, input_var_names, df){

df %>%
  mutate(...)

}

Where an indefinite number of new variables are generated. Their names use each element of a character vector new_var_names which has variable length. They are generated using as inputs the variables named in the character vector input_var_names using some functions f1 and f2.

Also ideally this should be done within mutate and without using mapping or looping procedures.

Is it possible to adapt mutate to do this ?

Thanks in advance.

2
where are f1 and f2 defined? - Abdessabour Mtk

2 Answers

2
votes

Here's an approach with across and rename_at. Who knows when rename will have across functionality added:

my_fun <- function(new_var_names, input_var_names, df){
  df %>%
    mutate(across(.cols = one_of(input_var_names), .names = "New.{.col}",
                  ~ . * 100)) %>%
    rename_at(vars(paste0("New.",input_var_names)),~new_var_names)
}

my_fun(c("NewX1","NewX2"),c("X1","X2"),data)
          X1       X2       X3        X4     NewX1    NewX2
1  76.512308 59.52818 35.45349 53.071453 7651.2308 5952.818
2  90.432867 53.60952 55.91350 87.441985 9043.2867 5360.952
3  82.226977 39.00973 14.58712 87.100901 8222.6977 3900.973
4   8.071753 32.63577 78.70822  3.345176  807.1753 3263.577
5   1.385738 81.03024 88.79939 97.613080  138.5738 8103.024
6   6.167663  5.15003 21.20549 49.532196  616.7663  515.003
7  86.789458 37.01053 77.29167 39.527862 8678.9458 3701.053
8  58.048272 85.80310 60.03993 42.337941 5804.8272 8580.310
9  32.070415 70.09671 95.80930 10.199656 3207.0415 7009.671
10 95.987113 68.76416 16.71015 17.019112 9598.7113 6876.416

You can replace ~ . * 100 with whatever function you want.

Sample Data:

data <- data.frame(replicate(4,runif(10,1,100)))
-1
votes

Sure you can, look this:

data <- data.frame(L=letters,X=runif(26),Y=rnorm(26))

# Make a Cumsum in X and Y at the same time.

my_fun <- function(new_var_names, input_var_names, df) {
      
      df %>% mutate(across(.cols = input_var_names, 
                           .fns  = cumsum,
                           .names = paste0(new_var_names,'{.col}') ))
      
}

my_fun(new_var_names="cumsum_",input_var_names=c("X","Y"),df=data)


# Make a Cumsum and  CumMax in X and Y at the same time.

my_fun <- function(new_var_names, input_var_names, df) {
      
      df %>% mutate(across(.cols = input_var_names, 
                           .fns  = list(CumSum=cumsum,CumMax=cummax),
                           .names = paste0(new_var_names,'{.fn}_{.col}') ))
      
}

my_fun(new_var_names="New_",input_var_names=c("X","Y"),df=data)