user7446890
user7446890

Reputation: 121

Using paste0 in deriving the denominator from the numerator using column names in dplyr mutate across

I am trying to create a function that takes in as numerator a column using column name and denominator using the same column name but includes a character and call the function in dplyr mutate across.

This is my attempt:

mtcars <- data.frame(f1_nom = c(1,2,5,7), f2_nom = c(3,4,2,8),f3_nom = c(1,2,5,7), f4_nom = c(3,4,2,8),f5_nom = c(2,3,5,1), f6_nom = c(3,4,3,7), f7 = c(1,2,4,7),
                     f1_nom_wt = c(1,3,1,2),f2_nom_wt = c(6,8,5,9),f3_nom_wt = c(1,1,1,2),f4_nom_wt = c(3,3,3,2),f5_nom_wt = c(5,8,5,1),f5_nom_wt = c(6,11,1,2))

library(rlang)
f <- function(var, colName){
  (fld+1)/(colName+1)
}
mtcars %>%
  mutate(across(f1_nom:f6_nom, ~ f(.x, paste0(.x,"_wt")), .names = "{col}_xyz"))

What I want is for the function to do this:

f1_nom/f1_nom_wt

I have over a two hundred of these rows f1_nom:f100_nom and f1_nom_wt:f100_nom_wt.

I know am doing it wrong cos am passing a var and characters paste0.

Thanks in advance for your help.

Upvotes: 0

Views: 117

Answers (2)

Ronak Shah
Ronak Shah

Reputation: 389335

Well, / can directly be applied on a dataframe. We can create two groups of dataframe and divide them directly.

wt_cols <- grep('wt', names(df), value = TRUE)
cols <- sub('_wt', '', wt_cols)
df[paste0(cols, '_xyz')] <- df[cols]/df[wt_cols]
df

data

df <- data.frame(f1_nom = c(1,2,5,7), f2_nom = c(3,4,2,8),f3_nom = c(1,2,5,7), 
                 f4_nom = c(3,4,2,8),f5_nom = c(2,3,5,1), f6_nom = c(3,4,3,7),
                 f1_nom_wt = c(1,3,1,2),f2_nom_wt = c(6,8,5,9),f3_nom_wt = c(1,1,1,2),
                 f4_nom_wt = c(3,3,3,2),f5_nom_wt = c(5,8,5,1),f6_nom_wt = c(6,11,1,2))

Upvotes: 1

G. Grothendieck
G. Grothendieck

Reputation: 270438

There are several problems with the question:

  1. the question overwrites a builtin mtcars which as mentioned in the comments is undesirable. We have called it DF in the Note at the end.
  2. There are two columns named f5_nom_wt and none named f6_nom_wt. We changed the second instance of f5_nom_wt to f6_nom_wt in the Note at the end.
  3. The description asks for the ratio of each _nom column to the corresponding _nom_wt column but the f function adds 1 to the numerator before dividing. We will assume we want the simple ratio but it is simple enough to change it.

To do this we use across twice.

res <- DF %>%
         mutate(across(f1_nom:f6_nom, .names = "{.col}_xyz") / 
                across(f1_nom_wt:f6_nom_wt))

giving:

> str(res)
'data.frame':   4 obs. of  19 variables:
 $ f1_nom    : num  1 2 5 7
 $ f2_nom    : num  3 4 2 8
 $ f3_nom    : num  1 2 5 7
 $ f4_nom    : num  3 4 2 8
 $ f5_nom    : num  2 3 5 1
 $ f6_nom    : num  3 4 3 7
 $ f7        : num  1 2 4 7
 $ f1_nom_wt : num  1 3 1 2
 $ f2_nom_wt : num  6 8 5 9
 $ f3_nom_wt : num  1 1 1 2
 $ f4_nom_wt : num  3 3 3 2
 $ f5_nom_wt : num  5 8 5 1
 $ f6_nom_wt : num  6 11 1 2
 $ f1_nom_xyz: num  1 0.667 5 3.5
 $ f2_nom_xyz: num  0.5 0.5 0.4 0.889
 $ f3_nom_xyz: num  1 2 5 3.5
 $ f4_nom_xyz: num  1 1.333 0.667 4
 $ f5_nom_xyz: num  0.4 0.375 1 1
 $ f6_nom_xyz: num  0.5 0.364 3 3.5

Note

The input used is

DF <-
  data.frame(f1_nom = c(1,2,5,7), f2_nom = c(3,4,2,8),
             f3_nom = c(1,2,5,7), f4_nom = c(3,4,2,8),
             f5_nom = c(2,3,5,1), f6_nom = c(3,4,3,7), 
             f7 = c(1,2,4,7),
             f1_nom_wt = c(1,3,1,2), f2_nom_wt = c(6,8,5,9),
             f3_nom_wt = c(1,1,1,2), f4_nom_wt = c(3,3,3,2),
             f5_nom_wt = c(5,8,5,1), f6_nom_wt = c(6,11,1,2))

Upvotes: 1

Related Questions