rschen
rschen

Reputation: 31

Loop mutating multiple columns in R

I am relatively new to using R and I need some help creating a loop to mutate multiple columns. I am trying to create a column making a calculation per sample, using a wide-format dataframe. My dataframe looks something similar to this:

df<- data.frame("count1" = c(1,2,3,4), "total1" = c(5,6,8,9), "count2" = c(4,3,2,1), "total2" = c(9,8,6,5))

where count1 and total 1 are of the same sample, and I want to mutate a column for each sample using the formula

df <- df %>% mutate(percent1 = count1/total1)

I am trying to create a loop to mutate these columns automatically, as I have over a hundred samples/columns. I am not sure if I have to melt the dataframe first, but as the data is more complex than described above this is not desired. I have tried multiple ways to create the loop such as

for (i in 1:nrow(samples)){
df <- df %>% mutate(paste("percent", i) = df$(paste("count"), i) / df$(paste"total", i)
}

But as it's not working I'd really appreciate any help

Upvotes: 2

Views: 1051

Answers (3)

user63230
user63230

Reputation: 4708

As long as your variables are in order, you could use purrr::map2:

library(tidyverse)
df[paste0("percent", 1:2)] <- map2(df %>% select(starts_with("count")), 
                                    df %>% select(starts_with("total")),  ~ .x/.y)
df
#   count1 total1 count2 total2  percent1  percent2
# 1      1      5      4      9 0.2000000 0.4444444
# 2      2      6      3      8 0.3333333 0.3750000
# 3      3      8      2      6 0.3750000 0.3333333
# 4      4      9      1      5 0.4444444 0.2000000

Upvotes: 0

s_baldur
s_baldur

Reputation: 33753

Or without a loop:

n <- nrow(samples)
df[paste0('percent', 1:n)] <- 
  df[grep('count', names(df))] / df[grep('total', names(df))]

#   count1 total1 count2 total2  percent1  percent2
# 1      1      5      4      9 0.2000000 0.4444444
# 2      2      6      3      8 0.3333333 0.3750000
# 3      3      8      2      6 0.3750000 0.3333333
# 4      4      9      1      5 0.4444444 0.2000000

Upvotes: 0

Miff
Miff

Reputation: 7951

This is probably easier without using dplyr, as:

for (i in 1:nrow(samples)){
  df[[paste0("percent", i)]] <- df[[paste0("count", i)]] / df[[paste0("total", i)]]
}

Upvotes: 1

Related Questions