2013-04-16 58 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安装该软件包。