'How to calculate ratio between 2 columns in R (with a function)?

we are running an experiment that checks the effect of brand on product value. In order to calculate the results, we first need to calculate the ratio between 2 answers to the same product. We want to do it by a function and not manual. for example

prod1_nobrand prod1_brand prod2_nobrand prod2_brand
1             2           4             8
2             6           5             20

enter image description here

we want to create a new column for each ratio for example

prod1_ratio prod2_ratio
2           2
3           4

any idea how to do that? thank you!



Solution 1:[1]

The simple base R way to do that would be as follows...

yourdataframe$new_ratio_col <- yourdataframe$prod1 / yourdataframe$prod2

Solution 2:[2]

I'm not 100% sure I'm understanding your ask correctly. But my feeling is that you should familiarize yourself with dplyr functions. You can use the mutate function to create new columns in this way:

library(dplyr)

df %>%
mutate(prod1_ratio = prod1_nobrand  / prod2 prod1_brand)

Solution 3:[3]

One option is the put it into long form, calculate the ratio, then pivot back to wide form with tidyverse.

library(tidyverse)

df %>%
  pivot_longer(everything(), names_to = c("num", ".value"), names_sep = "_") %>%
  mutate(ratio = brand / nobrand) %>% 
  select(-ends_with("brand")) %>% 
  group_by(num) %>% 
  mutate(rowid = row_number()) %>% 
  pivot_wider(names_from = "num", values_from = "ratio", names_glue = "{num}_ratio") %>% 
  select(-rowid)

Output

  prod1_ratio prod2_ratio
        <dbl>       <dbl>
1           2           2
2           3           4

Data

df <- structure(list(prod1_nobrand = 1:2, prod1_brand = c(2L, 6L), 
    prod2_nobrand = 4:5, prod2_brand = c(8L, 20L)), class = "data.frame", row.names = c(NA, 
-2L))

Solution 4:[4]

In case the columns are paired like in the given example c(FALSE, TRUE) and c(TRUE, FALSE) could be used to subset and make the division.

y <- x[c(FALSE, TRUE)] / x[c(TRUE, FALSE)]
names(y) <- sub("_.*", "_ratio", names(y))
y
#  prod1_ratio prod2_ratio
#1           2           2
#2           3           4

Data:

x <- data.frame(prod1_nobrand = 1:2, prod1_brand = c(2L, 6L),
                prod2_nobrand = 4:5, prod2_brand = c(8L, 20L))

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Brandon Rose
Solution 2 hachiko
Solution 3 AndrewGB
Solution 4 GKi