Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calculate row-wise proportions

Tags:

dataframe

r

apply

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.

like image 391
Rachit Agrawal Avatar asked Apr 16 '13 09:04

Rachit Agrawal


People also ask

How do you find the proportion of a row?

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.

How do I get row proportions in R?

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.

How do I sum all 5 rows in R?

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.

What does rowwise () do in R?

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.


2 Answers

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
like image 62
CHP Avatar answered Sep 18 '22 19:09

CHP


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? :)

like image 42
A5C1D2H2I1M1N2O1R2T1 Avatar answered Sep 16 '22 19:09

A5C1D2H2I1M1N2O1R2T1