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

R中数据表中行的几何平均数,r,data.table,R,Data.table,我有一个数据表,我想计算几列中每一行的几何平均数。一些值将有零,所以我需要排除这些值 维基上的几何平均值是:“几何平均值定义为n个数字乘积的第n个根”,因此对于2个数字,它只是它们乘积的平方根 在我的例子中,第n个根在每一行上都会有所不同,这取决于其中有多少值是非零的 在我下面的示例中,结果列的前两行计算如下: 1:(a*c)^(1/2) 2:(a*b*c)^(1/3) 所以我需要公式来看看a:c列,取非零值的乘积,然后取有多少个非零值的第n个根 library(data.table) dt &

我有一个数据表,我想计算几列中每一行的几何平均数。一些值将有零,所以我需要排除这些值

维基上的几何平均值是:“几何平均值定义为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))
库(data.table)

dt我们可以尝试使用
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

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

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
库(matrixStats)

m1假设所有非负值,这也会起作用

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
dt$Resultprod(a)^(1/长度(a))给出向量a的几何平均值

其他选项:

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

m1是否为“结果”预期输出所有数字均为非负?抱歉,结果为预期输出且所有值均为非负。代码块“dt[,result2…”返回错误…eval中的错误(expr,envir,enclose):对象“v1”不是found@MidnightDataGeek你有哪个版本的
data.table
呢?我用的是
1.10.0
我用的是1.9.6。我修改了下面的答案,严格来说它仍然是一个“data.table”方法吗?速度对我来说很关键,所以我试着用DT来处理所有事情,@MidnightDataGeek好的,这就是原因,用1.10.0,其他的使用
.SDcols
时也可以访问r列。是的,前两个是data.table方法。但是,如果使用
apply
,它可以转换为
matrix
,使用
data也没有好处。table
可能更简单一些
dt[,Result:=round(Reduce(`*`,replace(.SD,.SD==0,1))^(1/rowSums(.SD!=0)),2)]
谢谢。我已经根据需要修改了它…
dt[,Result:=apply(.SD,1,函数(x)(prod(x[x!=0])^(1/sum(x!=0)),.SDcols=1:3]
m1 <- as.matrix(setDF(dt)[1:3])
exp(rowMeans(log(m1)))