Reputation: 121
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
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
Reputation: 270438
There are several problems with the question:
mtcars
which as mentioned in the comments is undesirable. We have called it DF
in the Note at the end.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._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
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