将每个单元格中的值除以跨列的特定行的几何平均值并对其进行对数转换
Divide value in each cell by the geometric mean of a specific row across columns and log-transform it
我想用跨列的特定行的几何平均值除以每个单元格中的值,并对其进行对数转换(自然对数)。
df1
col1 col2 col3
row1 1 777 6
row2 136 1 665
row3 0 100 97
结果
df_new
col1 col2 col3
row1 -2.81 3.83
row2
row3
第 1 行的计算示例
也许您可以尝试下面的代码,使用 as.matrix
在数学运算之前将数据框转换为矩阵。此外,您可以使用 Reduce(*,df1)
来实现 df1
.
中列的乘积
在这种情况下,单线解给出为:
df_new <- data.frame(log(as.matrix(df1)/Reduce(`*`,df1)**(1/ncol(df1))))
这样
> df_new
col1 col2 col3
row1 -2.815733 3.839707 -1.023974
row2 1.108508 -3.804147 2.695640
row3 NaN Inf Inf
这是对您问题的回答。有关 n 次根计算的替代公式,请参阅 this discussion。
# set up the data
df <- data.frame(c(1, 777, 6), c(136, 1, 665), c(0, 100, 97))
df <- t(df)
colnames(df) <- c("V1", "V2", "V3")
rownames(df) <- NULL
# define a function to calculate the nth root
nthroot <- function(x, n){
x^(1/n)
}
# define a function to do your required transformations
cell_transformer <- function(x) {
log(x/(nthroot(sapply(apply(df, 1, prod), sum), length(x))))
}
# apply the cell_transformer to your dataframe in a row-wise fashion
apply(df, 1, function(x) cell_transformer(x))
#> [,1] [,2] [,3]
#> V1 -2.815733 2.096922 -Inf
#> V2 2.851293 -3.804147 0.8010229
#> V3 Inf Inf Inf
由 reprex package (v0.3.0)
于 2020-02-04 创建
library(tidyverse)
geometric_mean <- function(x){
exp(sum(log(x), na.rm = TRUE) / length(x))
}
yourCalculation <- function(x){
log(x / geometric_mean(x))
}
myMatrix <- tribble(
~col1 ,~col2 ,~col3
, 1 , 777 , 6
, 136 , 1 , 665
, 0 , 100 , 97) %>%
as.matrix()
t(apply(myMatrix, 1, yourCalculation))
col1 col2 col3
[1,] -2.815733 3.839707 -1.023974
[2,] 1.108508 -3.804147 2.695640
[3,] NaN Inf Inf
几何平均值的重要性:
不要这样计算它们:prod(x)^(1/length(x))
。这样做的问题是,对于已经是中等大小的向量 x
,当您将它们全部相乘时,您可能会 运行 跨越您的类型边界,因此它不会计算。 log()
-and-exp()
方式更好。
我想用跨列的特定行的几何平均值除以每个单元格中的值,并对其进行对数转换(自然对数)。
df1
col1 col2 col3
row1 1 777 6
row2 136 1 665
row3 0 100 97
结果
df_new
col1 col2 col3
row1 -2.81 3.83
row2
row3
第 1 行的计算示例
也许您可以尝试下面的代码,使用 as.matrix
在数学运算之前将数据框转换为矩阵。此外,您可以使用 Reduce(*,df1)
来实现 df1
.
在这种情况下,单线解给出为:
df_new <- data.frame(log(as.matrix(df1)/Reduce(`*`,df1)**(1/ncol(df1))))
这样
> df_new
col1 col2 col3
row1 -2.815733 3.839707 -1.023974
row2 1.108508 -3.804147 2.695640
row3 NaN Inf Inf
这是对您问题的回答。有关 n 次根计算的替代公式,请参阅 this discussion。
# set up the data
df <- data.frame(c(1, 777, 6), c(136, 1, 665), c(0, 100, 97))
df <- t(df)
colnames(df) <- c("V1", "V2", "V3")
rownames(df) <- NULL
# define a function to calculate the nth root
nthroot <- function(x, n){
x^(1/n)
}
# define a function to do your required transformations
cell_transformer <- function(x) {
log(x/(nthroot(sapply(apply(df, 1, prod), sum), length(x))))
}
# apply the cell_transformer to your dataframe in a row-wise fashion
apply(df, 1, function(x) cell_transformer(x))
#> [,1] [,2] [,3]
#> V1 -2.815733 2.096922 -Inf
#> V2 2.851293 -3.804147 0.8010229
#> V3 Inf Inf Inf
由 reprex package (v0.3.0)
于 2020-02-04 创建library(tidyverse)
geometric_mean <- function(x){
exp(sum(log(x), na.rm = TRUE) / length(x))
}
yourCalculation <- function(x){
log(x / geometric_mean(x))
}
myMatrix <- tribble(
~col1 ,~col2 ,~col3
, 1 , 777 , 6
, 136 , 1 , 665
, 0 , 100 , 97) %>%
as.matrix()
t(apply(myMatrix, 1, yourCalculation))
col1 col2 col3
[1,] -2.815733 3.839707 -1.023974
[2,] 1.108508 -3.804147 2.695640
[3,] NaN Inf Inf
几何平均值的重要性:
不要这样计算它们:prod(x)^(1/length(x))
。这样做的问题是,对于已经是中等大小的向量 x
,当您将它们全部相乘时,您可能会 运行 跨越您的类型边界,因此它不会计算。 log()
-and-exp()
方式更好。