Reputation: 1572
Given a dataframe like this:
id v1 v2 v3 v4
1 10 20 60 10
2 10 10 10 70
3 50 25 10 15
I would like to get their rowwise % like this:
id v1 v2 v3 v4 p1 p2 p3 p4
1 10 20 60 10 0.1 0.2 0.6 0.1
2 10 10 10 70 0.1 0.1 0.1 0.7
3 50 25 10 15 0.5 0.25 0.10 0.15
So I need to retain the original variables and create new ones that reflect their relative %, in reality the variables go all the way to 55 so I'm looking for a simple solution that does not require to calculate each value individually.
Upvotes: 0
Views: 40
Reputation: 50668
Here is a tidyverse
option
library(tidyverse)
left_join(df, df %>%
gather(k, v, -id) %>%
group_by(id) %>%
mutate(frac = v / sum(v), v = NULL, k = str_replace(k, "v", "p")) %>%
spread(k, frac))
# id v1 v2 v3 v4 p1 p2 p3 p4
#1 1 10 20 60 10 0.1 0.20 0.6 0.10
#2 2 10 10 10 70 0.1 0.10 0.1 0.70
#3 3 50 25 10 15 0.5 0.25 0.1 0.15
df <- read.table(text =
"id v1 v2 v3 v4
1 10 20 60 10
2 10 10 10 70
3 50 25 10 15", header = T)
Upvotes: 0
Reputation: 32548
setNames(object = df1[,-1]/rowSums(df1[,-1]),
nm = gsub("[(v)\\d+]", "p", colnames(df1[,-1])))
# p1 p2 p3 p4
#1 0.1 0.20 0.6 0.10
#2 0.1 0.10 0.1 0.70
#3 0.5 0.25 0.1 0.15
Upvotes: 2