Дискретизация равных частот в R - PullRequest
5 голосов
/ 20 апреля 2011

У меня проблемы с поиском функции в R, которая выполняет дискретизацию по частоте. Я наткнулся на пакет 'infotheo', но после некоторого тестирования я обнаружил, что алгоритм не работает. Кажется, что dprep больше не поддерживается в CRAN.

РЕДАКТИРОВАТЬ:

Для ясности, мне не нужно разделять значения между ячейками. Я действительно хочу равную частоту, не имеет значения, если одно значение окажется в двух бинах. Например:

c(1,3,2,1,2,2) 

должен дать корзину c(1,1,2) и одну c(2,2,3)

Ответы [ 8 ]

7 голосов
/ 20 апреля 2011

РЕДАКТИРОВАТЬ: учитывая вашу реальную цель, почему бы вам просто не сделать (исправлено):

 EqualFreq2 <- function(x,n){
    nx <- length(x)
    nrepl <- floor(nx/n)
    nplus <- sample(1:n,nx - nrepl*n)
    nrep <- rep(nrepl,n)
    nrep[nplus] <- nrepl+1
    x[order(x)] <- rep(seq.int(n),nrep)
    x
}

Возвращает вектор с индикаторами, для которых они предназначены.Но так как некоторые значения могут присутствовать в обеих ячейках, вы не можете определить пределы ячейки.Но вы можете сделать:

x <- rpois(50,5)
y <- EqualFreq2(x,15)
table(y)
split(x,y)

Оригинальный ответ:

Вы можете просто использовать cut() для этого:

EqualFreq <-function(x,n,include.lowest=TRUE,...){
    nx <- length(x)    
    id <- round(c(1,(1:(n-1))*(nx/n),nx))

    breaks <- sort(x)[id]
    if( sum(duplicated(breaks))>0 stop("n is too large.")

    cut(x,breaks,include.lowest=include.lowest,...)

}

Что дает:

set.seed(12345)
x <- rnorm(50)
table(EqualFreq(x,5))

 [-2.38,-0.886] (-0.886,-0.116]  (-0.116,0.586]   (0.586,0.937]     (0.937,2.2] 
             10              10              10              10              10 

x <- rpois(50,5)
table(EqualFreq(x,5))

 [1,3]  (3,5]  (5,6]  (6,7] (7,11] 
    10     13     11      6     10 

Как вы видите, для дискретных данных в большинстве случаев оптимальное равное объединение является довольно невозможным, но этот метод дает вам наилучшее возможное объединение.

5 голосов
/ 21 апреля 2011

Как насчет?

a <- rnorm(50)
> table(Hmisc::cut2(a, m = 10))

[-2.2020,-0.7710) [-0.7710,-0.2352) [-0.2352, 0.0997) [ 0.0997, 0.9775) 
               10                10                10                10 
[ 0.9775, 2.5677] 
               10 
5 голосов
/ 20 апреля 2011

Подобные вещи также довольно легко решаются с помощью (злоупотребления?) Инфраструктуры построения графика из решетки, в частности функции co.intervals():

cutEqual <- function(x, n, include.lowest = TRUE, ...) {
    stopifnot(require(lattice))
    cut(x, co.intervals(x, n, 0)[c(1, (n+1):(n*2))], 
        include.lowest = include.lowest, ...)
}

, которая воспроизводит отличный ответ @Joris:

> set.seed(12345)
> x <- rnorm(50)
> table(cutEqual(x, 5))

 [-2.38,-0.885] (-0.885,-0.115]  (-0.115,0.587]   (0.587,0.938]     (0.938,2.2] 
             10              10              10              10              10
> y <- rpois(50, 5)
> table(cutEqual(y, 5))

 [0.5,3.5]  (3.5,5.5]  (5.5,6.5]  (6.5,7.5] (7.5,11.5] 
        10         13         11          6         10

В последнем дискретном случае разрывы различны, хотя имеют одинаковый эффект;одни и те же наблюдения находятся в одних и тех же бункерах.

0 голосов
/ 17 октября 2018

Мы можем использовать пакет cutr с функцией what = "rough", внешний вид этикеток можно настроить по вкусу:

# devtools::install_github("moodymudskipper/cutr")
library(cutr)
smart_cut(c(1, 3, 2, 1, 2, 2), 2, "rough", brackets = NULL, sep="-")
# [1] 1-2 2-3 1-2 1-2 2-3 2-3
# Levels: 1-2 < 2-3
0 голосов
/ 29 ноября 2017

Вот еще одно решение с использованием mltools .

set.seed(1)
x <- round(rnorm(20), 2)
x.binned <- mltools::bin_data(x, bins = 5, binType = "quantile")
table(x.binned)

x.binned
[-2.21, -0.622)   [-0.622, 0.1)    [0.1, 0.526)  [0.526, 0.844)    [0.844, 1.6] 
              4               4               4               4               4 
0 голосов
/ 26 ноября 2017

Библиотека classInt создана «для выбора одномерных интервалов классов для отображения или других графических целей». Вы можете просто сделать:

dataset <- c(1,3,2,1,2,2) 

library(classInt)
classIntervals(dataset, 2, style = 'quantile')

, где 2 - количество желаемых лотков, а quantile style - квантильные разрывы Для этой функции доступно несколько styles: «fixed», «sd», «equal», «pretty», «quantile», «kmeans», «hclust», "bclust", "fisher" или "jenks". Проверьте документы для получения дополнительной информации.

0 голосов
/ 09 февраля 2017

Вот решение с одним вкладышем, вдохновленное ответом @Joris:

x <- rpois(50,5)
binSize <- 5
desiredFrequency = floor(length(x)/binSize)
split(sort(x), rep(1:binSize, rep(desiredFrequency, binSize)))
0 голосов
/ 07 декабря 2015

Вот функция, которая обрабатывает ошибку: 'breaks' are not unique и автоматически выбирает самое близкое значение n_bins к тому, которое вы установили.

equal_freq <- function(var, n_bins)
{
  require(ggplot2)

  n_bins_orig=n_bins

  res=tryCatch(cut_number(var, n = n_bins), error=function(e) {return (e)})
  while(grepl("'breaks' are not unique", res[1]) & n_bins>1)
  {
    n_bins=n_bins-1
    res=tryCatch(cut_number(var, n = n_bins), error=function(e) {return (e)})

  }
  if(n_bins_orig != n_bins)
    warning(sprintf("It's not possible to calculate with n_bins=%s, setting n_bins in: %s.", n_bins_orig, n_bins))

  return(res)
}

Пример:

equal_freq(mtcars$carb, 10)

, которая извлекает переменную binned и следующее предупреждение:

It's not possible to calculate with n_bins=10, setting n_bins in: 5.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...