用于计算熵的向量化函数
Vectorizing function to calculate entropy
我正在编写一个函数来计算香农多样性指数。我有广泛的数据,每个值的观察百分比作为单独的变量,每一行代表一个不同的站点。根据数据集,我将有 2 到 7 个变量。我想为每一行计算信息索引。
。
我有一个循环函数,但它很慢,我正在寻求帮助对其进行矢量化。我也很高兴有一个 tidyverse 风格的解决方案。
我一直在考虑使用 entropy
包,但它似乎需要长格式的数据,虽然我可以扩展我的数据,但这似乎会不必要地慢。我目前有 20k 个站点,每个站点有 100 到 1000 个观测值,这些观测值已经汇总到宽格式百分比分布中。 同样适用于长格式数据。
示例数据
# Wide data, between 2 and 7 columns recording the percent of observations with each value, example using 3
df <- data.frame(
site = 1:3,
l1 = c(.33, .5, 0),
l2 = c(.33, .5, 0),
l3 = c(.33, 0, 1)
)
电流循环功能
entropy <- function(df, vars) {
entropy_calc <- function(df, i, vars) {
sum <- 0
for (j in vars) {
x <- df[i,j]
if(x != 0) { # skip zeros
sum <- sum + x * log(x)
}
}
return(-sum)
}
entropy <- rep(NA, nrow(df))
for(i in 1:nrow(df)) {
entropy[i] <- entropy_calc(df, i, vars)
}
return(as.numeric(entropy))
}
df$entropy <- entropy(df, 2:4)
这可以很容易地向量化,因为所需的底层函数已经向量化。您不需要手动跳过零,因为 log(0)
returns -Inf
和 0*log(0)
returns NaN
。通过指定 na.rm = TRUE
对单元格值求和时,可以省略 NaN
。
entropy <- function(p) rowSums(-(p * log(p)), na.rm = TRUE)
entropy(df[,2:4])
另请查看 vegan
包中的 diversity()
函数,它主要执行此操作以及其他可能性。
我正在编写一个函数来计算香农多样性指数。我有广泛的数据,每个值的观察百分比作为单独的变量,每一行代表一个不同的站点。根据数据集,我将有 2 到 7 个变量。我想为每一行计算信息索引。
我有一个循环函数,但它很慢,我正在寻求帮助对其进行矢量化。我也很高兴有一个 tidyverse 风格的解决方案。
我一直在考虑使用 entropy
包,但它似乎需要长格式的数据,虽然我可以扩展我的数据,但这似乎会不必要地慢。我目前有 20k 个站点,每个站点有 100 到 1000 个观测值,这些观测值已经汇总到宽格式百分比分布中。
示例数据
# Wide data, between 2 and 7 columns recording the percent of observations with each value, example using 3
df <- data.frame(
site = 1:3,
l1 = c(.33, .5, 0),
l2 = c(.33, .5, 0),
l3 = c(.33, 0, 1)
)
电流循环功能
entropy <- function(df, vars) {
entropy_calc <- function(df, i, vars) {
sum <- 0
for (j in vars) {
x <- df[i,j]
if(x != 0) { # skip zeros
sum <- sum + x * log(x)
}
}
return(-sum)
}
entropy <- rep(NA, nrow(df))
for(i in 1:nrow(df)) {
entropy[i] <- entropy_calc(df, i, vars)
}
return(as.numeric(entropy))
}
df$entropy <- entropy(df, 2:4)
这可以很容易地向量化,因为所需的底层函数已经向量化。您不需要手动跳过零,因为 log(0)
returns -Inf
和 0*log(0)
returns NaN
。通过指定 na.rm = TRUE
对单元格值求和时,可以省略 NaN
。
entropy <- function(p) rowSums(-(p * log(p)), na.rm = TRUE)
entropy(df[,2:4])
另请查看 vegan
包中的 diversity()
函数,它主要执行此操作以及其他可能性。