Home > database >  Using paste0 in deriving the denominator from the numerator using column names in dplyr mutate acros
Using paste0 in deriving the denominator from the numerator using column names in dplyr mutate acros

Time:01-29

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.

CodePudding user response:

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

CodePudding user response:

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))
  •  Tags:  
  • Related