2013-04-16 90 views
10

我有一個數據幀:計算逐行比例

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 

在每一行中,我要計算每個值對應的比例(比率)。例如。對於列「val0」中的值,我想計算行valio /(val0 + val1 + val2)。

所需的輸出:

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 

誰能告訴我什麼是做到這一點的最好方法是什麼?這裏只有三列,但可以有很多列。

回答

4

而另一種選擇這樣的伎倆

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 
+0

+1非常好的使用'prop.table' –

+1

@Jilber,謝謝。實際上,它的靈感來源於你的解決方案,因爲我總是記得'prop.table'的描述,首先說它對於新手(我永遠是「掃地」)。 – A5C1D2H2I1M1N2O1R2T1

7

下應該使用sweep

sweep(x[,-1], 1, rowSums(x[,-1]), FUN="/") 
     val0  val1  val2 
1 0.08333333 0.3333333 0.5833333 
2 0.13333333 0.3333333 0.5333333 
3 0.16666667 0.3333333 0.5000000 
5

另一種選擇(雖然這是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 

從「de scription」在?prop.table幫助文件的部分:

這真是sweep(x, margin, margin.table(x, margin), "/")新手,但如果利潤率有長度爲零,那麼一個得到X /總和(X)。

因此,您可以看到,在下面,這與@ Jilber的解決方案非常相似。

而且...... R開發者對我們新手的體貼很不錯,不是嗎? :)

1

從看門包的功能ns_to_percents做到這一點:

library(janitor) 
ns_to_percents(x) 

    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 

這相當於ns_to_percents(x, denom = "row"),雖然"row"是默認的參數,所以不需要在這個例子中。

如果您顯示結果,您可能更喜歡janitor::adorn_crosstab

免責聲明:我創建了janitor包,但覺得適合發佈此;該功能是爲了完成這項任務而構建的,同時使代碼更加清晰,並且可以從CRAN安裝該軟件包。