我在R中找到执行等频离散化的功能时遇到了问题。我偶然发现了'infotheo'软件包,但经过一些测试后发现算法被破坏了。 CRAN似乎不再支持“dprep”。
编辑:
为清楚起见,我不需要分隔箱之间的值。我真的想要相同的频率,如果一个值最终在两个箱中,则无关紧要。例如:
c(1,3,2,1,2,2)
应该提供一个c(1,1,2)
和一个c(2,2,3)
答案 0 :(得分:7)
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
}
这会返回一个向量,其中包含指针所在的bin。但由于某些值可能存在于两个容器中,因此您无法定义容器限制。但你可以这样做:
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
如您所见,对于离散数据,在大多数情况下,最佳的相等分级是不可能的,但是这种方法可以为您提供最佳的分级。
答案 1 :(得分:5)
通过使用(滥用?)格子的条件图基础设施,特别是函数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
在后者,离散的情况下,断裂是不同的,尽管它们具有相同的效果;相同的观察结果都在同一个箱子中。
答案 2 :(得分:5)
怎么样?
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
答案 3 :(得分:0)
以下是处理错误的函数:'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.
答案 4 :(得分:0)
这是一个受@ Joris&#39;启发的单线解决方案。回答:
x <- rpois(50,5)
binSize <- 5
desiredFrequency = floor(length(x)/binSize)
split(sort(x), rep(1:binSize, rep(desiredFrequency, binSize)))
答案 5 :(得分:0)
创建classInt库&#34;用于选择用于映射或其他图形目的的单变量类间隔&#34;。你可以这样做:
dataset <- c(1,3,2,1,2,2)
library(classInt)
classIntervals(dataset, 2, style = 'quantile')
其中2
是您想要的分区数,quantile
style
提供分位数分隔符。有几个styles
可用于此功能:&#34;固定&#34;,&#34; sd&#34;,&#34;等于&#34;,&#34;漂亮&#34;,& #34;分位数&#34;,&#34; kmeans&#34;,&#34; hclust&#34;,
&#34; bclust&#34;,&#34; fisher&#34;或&#34; jenks&#34;。查看docs了解详情。
答案 6 :(得分:0)
这是使用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
答案 7 :(得分:0)
我们可以将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