R中数据表中行的几何平均值

时间:2017-01-19 11:59:22

标签: r data.table

我有一个数据表,我想计算几列上每行的几何平均值。有些值会有零,所以我需要将它们排除在外。

来自Wiki的几何平均值为:"几何平均值定义为n个数的乘积的第n个根"所以对于2个数字,它只是它们产品的平方根。

在我的情况下,第n个根将在每一行上有所不同,具体取决于其中有多少个值是非零。

在下面的示例中,结果列的前两行按如下方式计算:

1:(a * c)^(1/2)

2:(a * b * c)^(1/3)

所以我需要公式来查看列a:c,取非零值的乘积,然后取第n个根来确定有多少个非零值。

library(data.table)
dt <- data.table(a = c(0.5, 0.3,0,0.6), b = c(0,0.4,0.1,0), 
c = c(0.9,0.5,0.1,0), Result = c(0.67, 0.39, 0.1, 0.6))

4 个答案:

答案 0 :(得分:3)

我们可以尝试使用data.table方法

dt[, v1 := Reduce(`+`, lapply(.SD, function(x) x!=0)), .SDcols = 1:3]
dt[, result2 := round((Reduce(`*`, lapply(.SD, function(x) 
    replace(x, x==0, 1))))^(1/v1), 2), .SDcols = 1:3][, v1 := NULL][]
#    a   b   c Result result2
#1: 0.5 0.0 0.9   0.67    0.67
#2: 0.3 0.4 0.5   0.39    0.39
#3: 0.0 0.1 0.1   0.10    0.10
#4: 0.6 0.0 0.0   0.60    0.60

或者另一个效率较低的选项是按行序列分组,然后在每行上执行

dt[, result2 := {
           u1 <- unlist(.SD)
           round(prod(u1[u1!=0])^(1/sum(u1!=0)), 2)} , 1:nrow(dt), .SDcols = 1:3]
dt
#     a   b   c Result result2
#1: 0.5 0.0 0.9   0.67    0.67
#2: 0.3 0.4 0.5   0.39    0.39
#3: 0.0 0.1 0.1   0.10    0.10
#4: 0.6 0.0 0.0   0.60    0.60

注意:这两种方法都是data.table方法。

或@DavidArenburg提供的其他选项

dt[, Result := round(Reduce(`*`, replace(.SD, .SD == 0, 1))^(1/rowSums(.SD != 0)), 2)]

另一个矢量化选项是转换为matrix

library(matrixStats)
m1 <- as.matrix(setDF(dt)[1:3])
round(rowProds(replace(m1, !m1, 1))^(1/rowSums(m1!=0)), 2)
#[1] 0.67 0.39 0.10 0.60

答案 1 :(得分:2)

这也可以,假设所有非负值。

dt$Result <- apply(dt, 1, function(x) (prod(x[x!=0]))^(1/sum(x!=0)))
dt
#     a   b   c    Result
#1: 0.5 0.0 0.9 0.6708204
#2: 0.3 0.4 0.5 0.3914868
#3: 0.0 0.1 0.1 0.1000000
#4: 0.6 0.0 0.0 0.6000000

答案 2 :(得分:0)

prod(a)^(1 / length(a))给出向量a的几何平均值

答案 3 :(得分:0)

其他选项:

m1 <- as.matrix(setDF(dt)[1:3])
exp(rowMeans(log(m1)))