Reputation: 31
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
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
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
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