R中的分箱程序?

时间:2017-09-24 18:57:40

标签: r binning

我正在努力将以下分箱"算法/程序"放入R代码/脚本中,这可能类似于用于分箱核密度估算的那些:

说我们有一些数据:

set.seed(12345) # setting seed
x<-rnorm(100)   # generating data

和用于估计的网格(例如,核密度估计):

y<-seq(from=min(x)-1, to=max(x)+1, by=0.01) # grid for binning

  1. 目标是将y分成若干个等间隔/分箱,以便每个分箱至少包含一个来自x的观察(不允许分箱数=空分箱) 。对于这个特定的例子,我知道这个数量的二进制数等于17,但我希望R自动确定这样的&#34;最优/最大值&#34;相应的箱柜数y

  2. 假设确定了所需的等间隔/分区数,然后可以使用(至少从我的有效谷歌搜索中)以下内容y

  3. nbins<-cut(y, 17) # binning

    能够很好地完成工作,因为它完全按照我想要的方式分割y但是如何确定每个bin的中心(可能使用median()?)以及{{1哪个落入每个垃圾箱?

    有一个有趣的包x具有非常好的功能,但是,它似乎并没有提供我正在寻找的东西。我会非常感谢任何提示,技巧和建议......

    binr

    首先,我要特别感谢@missuse的帮助,努力和投入。其次,我想为一些EDIT: an example of a code with which I ended up with for my calculations. R函数的无知(希望由于缺乏R的经验和一般编程)而道歉。

    我正在改造和试验为我的计算开发的代码@missuse,但是,不断出现base的问题,并且经常需要手动调整不同的数据集。特别是,当我试验由我的数据的样本分位数确定的断点时。另外x函数在我看来似乎非常敏感(注意:由于我的目标,数据等,这可能是非常主观的)。所以,前几天厌倦了不断调整并通过cut命令执行各种R函数,help()来到我的救援并解决了几乎所有的binning问题。以下是非常直接的说明,以确定每个箱子中落入多少hist()以及如何确定每个箱柜的箱中心:

    x

    上面我假设选择了所需的休息时间,你可以根据你想要的方式建立一个基于hist(x, breaks=c(-5:5), plot=FALSE)$counts # for bin counts hist(x, breaks=c(-5,5), plot=FALSE)$mids # for bin centers 功能的功能,并相应地削减网格以进行估算。下面的@missuse为使用cut设置中断提供了良好的基础,只需确保您的数据跨越cut中的breaks规范。

1 个答案:

答案 0 :(得分:1)

也许是这样的:

数据:

 set.seed(12345) # setting seed
 x<-rnorm(100)
 y<-seq(from=min(x)-1, to=max(x)+1, by=0.01) 
 nbins<-cut(y, 17)

第1步:

对于所有可能的剪切,查找x中的任何元素是否在所有bin中:

p =lapply(3 : length(x), function(i){
  nbins<-cut(y, i)
  z = lapply(levels(nbins), function(j) y[nbins == j])
  sumi = lapply(z, function(i) {
    mini = min(i)
    maxi = max(i)
    sum(mini <= x & x <= maxi)
  }
  )
  return(sum(unlist(sumi)>0) == length(sumi))
}
)

which(unlist(p)), only first 4 satisfy the rule, so 3, 4, 5, 6 

第2步:

根据bin:

将值放入列表中
z = lapply(levels(nbins), function(x) y[nbins == x] )

执行每个列表项的兴趣功能

lapply(z, median) #median for each bin

lapply(z, function(i) {
  mini = min(i)
  maxi = max(i)
  sum(mini <= x & x <= maxi)
}
) #number of elements of x in each bin

根据结果,某些箱子中有0个元素来自x,因此箱子17在步骤1中无法解决您的问题。

编辑:关于遗失x的问题:

sum(unlist(lapply(z, function(i) {
  mini = min(i)
  maxi = max(i)
  sum(mini <= x & x <= maxi)
}
))) is less than 100 in many cases

缺少哪个x:

nbins<-cut(y, 8) 
    z = lapply(levels(nbins), function(x) y[nbins == x])
    gix = lapply(z, function(i) {
      mini = min(i)
      maxi = max(i)
      x[mini <= x & x <= maxi]
    }
    )
  x[!x %in% unlist(gix)]

 #-1.6620502 -0.8115405 

所以他们应该在垃圾箱(-1.67,-0.812](-0.812,0.0446]   并且实际上接近垃圾箱截止。

这种情况正在发生,因为y以小数点后两位舍入。例如,如果我们将一个序列:0.01,0.02,0.03和0.04分开并将其切割成2个分箱,将数据分成0.025,我们将得到bin 1:0.01 - 0.02和bin 2:0.03 - 0.04,如果我们再尝试从范围0.01 - 0.04中分配一些随机x值,仅基于区间中存在的y值,我们不会在0.02 - 0.03范围内分配任何值 - 因此缺少值。

一种可能的解决方案是将x舍入为2,因为您已经将seq四舍五入为2.或者执行seq,其中y值舍入为4 - 6位小数并且舍入{ {1}}因此。或者,不是在bin i中根据xx分配min(yi),而是将max(yi)替换为min(yi) <= x(来自bin i-1的max(yi)),并将max(yi-1) < x替换为x <= max(yi)。 这是最简单的解决方案,舍入x为2位小数。

x < min(yi+1)

这将至少解决缺少x元素的问题

优化问题的解决方案是相同的

p =lapply(2 : length(x), function(i){ nbins<-cut(y, i) z = lapply(levels(nbins), function(j) y[nbins == j]) sumi = lapply(z, function(i) { mini = min(i) maxi = max(i) p = round(x, 2) sum(mini <= p & p <= maxi) } ) return(sum(unlist(sumi)>0) == length(sumi)) } ) ,只有前4个满足规则,所以3,4,5,6