Автоматизируйте несколько вычислений в R с помощью фреймов данных

У меня есть ряд векторов, каждый из которых назван акцией, например FB для Facebook Inc. Таким образом, у меня есть более 70 серий векторов внутри фреймов данных, например, GEEK, IPAS, JCON и т. д. По каждой паре акций скажем, например, GEEK и JCON, я должен рассчитать меру, называемую взаимной информацией. Я написал некоторый код, чтобы найти эту меру для пары акций, и это так.

Чтобы найти entropyz (энтропия X, Y, скажем, двумерная энтропия GEEK и JCON возвращается)

denz<-kde2d(x,y, n=512, lims=c(xlim,ylim))
z<-denz$z
cell_sizez<-(diff(xlim)/512) * (diff(ylim)/512)
normz<-sum(z)*cell_sizez
integrandz<-z*log(z)
entropyz<-sum(integrandz)*cell_sizez
entropyz<-entropyz/normz

Чтобы найти entropyx (возвращается энтропия X, скажем, GEEK)

denx<-kde(x=x,gridsize = 512, xmin=xlim[1], xmax = xlim[2])
zx<-denx$estimate
cell_sizex<-(diff(xlim)/512) 
normx<-sum(zx)*cell_sizex
integrandx<-zx*log(zx)
entropyx<-sum(integrandx)*cell_sizex
entropyx<-entropyx/normx

Чтобы найти entropyy (энтропия Y, скажем, возвращает JCON)

deny<-kde(x=y,gridsize = 512, xmin=ylim[1], xmax = ylim[2])
zy<-deny$estimate
cell_sizey<-(diff(ylim)/512) 
normy<-sum(zy)*cell_sizey
integrandy<-zy*log(zy)
entropyy<-sum(integrandy)*cell_sizey
entropyy<-entropyy/normy

Наконец, чтобы найти общую информацию GEEK и JCON

MI <- entropyx+entropyy-entropyz

Итак, я нашел взаимную информацию для X и Y (две акции выше). Но я должен рассчитать эту меру для более чем 70 акций (векторов) с 70 * 69/2 итераций = 2415; Это похоже на создание корреляционной матрицы, потому что это попарное сравнение. Вопрос в том, знает ли кто-нибудь способ заставить R найти эту общую информацию для всех пар (x,y) в моем наборе данных. Другими словами, повторять этот код для каждой пары в кадре данных, создавая таким образом парную матрицу.

Большое спасибо!


person Alex Quintino Barbi    schedule 25.05.2016    source источник
comment
В качестве отправной точки один из способов получить каждую попарную комбинацию вектора — это combn.   -  person lmo    schedule 25.05.2016
comment
Я обновил свой ответ, чтобы сделать его лучше, хотя мне интересно, как рассчитываются xlim и ylim и различаются ли они для каждой пары или нет.   -  person jamieRowen    schedule 25.05.2016
comment
@jamieRowen Эти пределы представляют собой просто диапазон x и y, то есть минимальное и максимальное значение этих временных рядов. Спасибо за Ваш ответ.   -  person Alex Quintino Barbi    schedule 27.05.2016
comment
@jamieRowen, я использовал приведенный ниже код, и он не сработал. У меня есть строки с такими именами: a, b, c, d, e, (...) z (...) aa, ab (...) ak; Итак, я использую эту функцию для вычисления взаимной информации для x и y. Таким образом, при вызове последней части вашего кода (для применения комбинаций) он вернул мне «Ошибка в kde2d(x, y, n = 8, lims = c(xlim, ylim)) : векторы данных должны быть одинаковыми длина' ; но все мои векторы имеют одинаковую длину; Вы знаете, что происходит? Спасибо!   -  person Alex Quintino Barbi    schedule 27.05.2016
comment
@jamieRowen, вы поняли, как рассчитываются «xlim» и «ylim»? Спасибо.   -  person Alex Quintino Barbi    schedule 14.09.2016


Ответы (1)


Если вы создадите функцию MI, которая принимает два ваших вектора данных и возвращает значение, вы можете использовать что-то вроде следующего для создания симметричной квадратной матрицы с результатами. Если мы предположим, что ваши данные находятся во фрейме данных df, мы могли бы сделать

MI = function(x,y,xlim,ylim){
  denz<-kde2d(x,y, n=512, lims=c(xlim,ylim))
  z<-denz$z
  cell_sizez<-(diff(xlim)/512) * (diff(ylim)/512)
  normz<-sum(z)*cell_sizez
  integrandz<-z*log(z)
  entropyz<-sum(integrandz)*cell_sizez
  entropyz<-entropyz/normz

  denx<-kde(x=x,gridsize = 512, xmin=xlim[1], xmax = xlim[2])
  zx<-denx$estimate
  cell_sizex<-(diff(xlim)/512) 
  normx<-sum(zx)*cell_sizex
  integrandx<-zx*log(zx)
  entropyx<-sum(integrandx)*cell_sizex
  entropyx<-entropyx/normx

  deny<-kde(x=y,gridsize = 512, xmin=ylim[1], xmax = ylim[2])
  zy<-deny$estimate
  cell_sizey<-(diff(ylim)/512) 
  normy<-sum(zy)*cell_sizey
  integrandy<-zy*log(zy)
  entropyy<-sum(integrandy)*cell_sizey
  entropyy<-entropyy/normy

  return(entropyx+entropyy-entropyz)
}
df = data.frame(1:10,1:10,1:10,1:10,1:10)
matrix(
  apply(
    expand.grid(
      seq_along(df),seq_along(df)),1,
    FUN = function(i,j) MI(df[,i],df[,j],xlim,ylim)
    ),
  nrow = ncol(df)
)

это работает, потому что expand.grid дает вам все комбинации индексов столбцов в кадре данных n ^ 2 на 2. Затем мы применяем функцию MI к каждому из них и сохраняем результат в матрице.

Изменить: отредактировано, чтобы сделать его более понятным.

person jamieRowen    schedule 25.05.2016
comment
@AlexQuintinoBarbi Я имею в виду, что вы можете обернуть все свои вычисления MI в функцию, которая принимает x и y, поскольку это то, что вы передаете различным другим функциям. Перечитывая ваш вопрос, я вижу, что я что-то пропустил в первый раз, вы говорите, что у вас есть 70 фреймов данных, а не 70 столбцов фрейма данных. Но kde2d принимает векторы значений, поэтому я сделал предположение, что каждая акция представляет собой единый вектор данных, каждый из ваших фреймов данных представляет собой один столбец? Можете ли вы склеить их вместе в один фрейм данных. Отредактировал ответ, чтобы было понятнее, что я имел в виду - person jamieRowen; 25.05.2016
comment
Я отредактировал вопрос, чтобы получить более четкое представление об этом. Как я уже отмечал ранее, я получаю два типа ошибок: первый: «Ошибка в kde2d(x, y, n = 8, lims = c(xlim, ylim)) : векторы данных должны быть одинаковой длины» и второй, Ошибка в is.finite(x): метод по умолчанию не реализован для типа «список». Я думаю, что могут быть некоторые проблемы с различными диапазонами x и y для первой ошибки. Насчет второго я, кажется, не знаю, потому что у меня нет списков. Спасибо! - person Alex Quintino Barbi; 27.05.2016