Функция векторизации для расчета энтропии - PullRequest
2 голосов
/ 04 марта 2020

Я пишу функцию для расчета индекса разнообразия Шеннона. У меня есть широкие данные с количеством наблюдений для каждого значения в виде отдельных переменных, где каждая строка представляет отдельный сайт. У меня будет от 2 до 7 переменных в зависимости от набора данных. Для каждой строки я хочу рассчитать информационный индекс.

equation.

У меня есть функция al oop, но она довольно медленная, и я ищу помощи для ее векторизации. Я также рад за решение в стиле Tidyverse.

Я смотрел на использование пакета entropy, но похоже, что данные ожидаются в полной форме, и хотя я мог бы расширить свои данные обратно, кажется, что это будет излишне медленным. В настоящее время у меня есть 20 тысяч сайтов с сотнями и тысячами наблюдений на сайт, которые уже были сведены в широкоформатные процентные распределения. Этот вопрос аналогично работает с данными полной формы.

Пример данных

# 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)
)

Текущий l oop функция

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)

1 Ответ

2 голосов
/ 04 марта 2020

Это можно легко векторизовать, поскольку необходимые базовые функции уже векторизованы. Вам не нужно пропускать нули вручную, потому что log(0) возвращает -Inf и 0*log(0) возвращает NaN. Вы можете опустить NaN при суммировании значений ячеек, указав na.rm = TRUE.

entropy <- function(p) rowSums(-(p * log(p)), na.rm = TRUE)

entropy(df[,2:4])

Также ознакомьтесь с функцией diversity() в пакете vegan, которая, по сути, делает это, помимо других возможностей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...