Reputation: 10996
library(tidyverse)
dat <- tribble(
~Scenario, ~V1, ~V2, ~V3, ~V4,
1, 0.97, 0.46, 0.79, 0.25,
1, 0.21, 0.45, 0.23, 0.63,
1, 0.95, 0.97, 0.07, 0.61,
1, 0.93, 0.79, 0.23, 0.86,
2, 0.22, 0.01, 0.42, 0.47,
2, 0.71, 0.17, 0.16, 0.88,
3, 0.73, 0.38, 0.10, 0.77,
3, 0.49, 0.37, 0.90, 0.52,
3, 0.99, 0.71, 0.66, 0.05,
3, 0.72, 0.75, 0.69, 0.01,
3, 0.15, 0.87, 0.12, 0.02,
4, 0.94, 0.30, 0.91, 0.99)
I'm adding four new columns to this data, where each new column represents the sum of each V1:V4 column grouped by Scenario:
dat_new <- dat %>%
group_by(Scenario) %>%
mutate_at(vars(-group_cols()), .funs = list(sum = sum))
I'm looking for a simple way to divide V1 by V1_sum, V2 by V2_sum and so on assuming that a) I have as many original v columns as I have sum columns and b) that the data is correctly ordered and following my pattern where I first have all my v columns followed by the sum columns.
I just asked a another question here on SO where the focus was on pivoting the data to long format and then transform it back to wide format, but I was wondering if there was an easier solution in the tidyverse.
Note: I could probably just loop through each column and divide it by the column 4 positions later, but I was looking for a more elegant solution.
Upvotes: 1
Views: 126
Reputation: 887391
We can expand the function inside list
instead of creating temporary sum
columns and then divide
library(dplyr)
dat %>%
group_by(Scenario) %>%
mutate_at(vars(-group_cols()), .funs = list(percentage = ~ ./sum(.)))
If it is from dat_new
, one option is map
library(purrr)
map2_dfc(dat %>%
select(V1:V4),
dat_new %>%
ungroup %>%
select(ends_with('sum')), `/`)
Or using base R
dat[2:5]/dat_new[6:9]
Upvotes: 2