I have a data frame:
x <- data.frame(id = letters[1:3], val0 = 1:3, val1 = 4:6, val2 = 7:9)
# id val0 val1 val2
# 1 a 1 4 7
# 2 b 2 5 8
# 3 c 3 6 9
Within each row, I want to calculate the corresponding proportions (ratio) for each value. E.g. for the value in column "val0", I want to calculate row-wise val0 / (val0 + val1 + val2).
Desired output:
id val0 val1 val2
1 a 0.083 0.33 0.583
2 b 0.133 0.33 0.533
3 c 0.167 0.33 0.5
Can anyone tell me what's the best way to do this? Here it's just three columns, but there can be alot of columns.
Row percentages are computed by dividing the count for a cell by the total sample size for that row. A row percent shows the proportion of people in a column category from among those in the row.
The proportion of row value in a data frame is equivalent to the cell value divided by the summation of the cell values belonging to that entire row. The sum of all the row proportion values in a data frame is equivalent to 1.
To find the sum of every n values in R data frame columns, we can use rowsum function along with rep function that will repeat the sum for rows.
rowwise() allows you to compute on a data frame a row-at-a-time. This is most useful when a vectorised function doesn't exist. Most dplyr verbs preserve row-wise grouping.
following should do the trick
cbind(id = x[, 1], x[, -1]/rowSums(x[, -1]))
## id val0 val1 val2
## 1 a 0.08333333 0.3333333 0.5833333
## 2 b 0.13333333 0.3333333 0.5333333
## 3 c 0.16666667 0.3333333 0.5000000
And another alternative (though this is mostly a pretty version of sweep
)... prop.table
:
> cbind(x[1], prop.table(as.matrix(x[-1]), margin = 1))
id val0 val1 val2
1 a 0.08333333 0.3333333 0.5833333
2 b 0.13333333 0.3333333 0.5333333
3 c 0.16666667 0.3333333 0.5000000
From the "description" section of the help file at ?prop.table
:
This is really
sweep(x, margin, margin.table(x, margin), "/")
for newbies, except that if margin has length zero, then one gets x/sum(x).
So, you can see that underneath, this is really quite similar to @Jilber's solution.
And... it's nice for the R developers to be considerate of us newbies, isn't it? :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With