我有一个数据表,我想计算几列上每行的几何平均值。有些值会有零,所以我需要将它们排除在外。
来自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))
答案 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)))