我正在努力将以下分箱"算法/程序"放入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
目标是将y
分成若干个等间隔/分箱,以便每个分箱至少包含一个来自x
的观察(不允许分箱数=空分箱) 。对于这个特定的例子,我知道这个数量的二进制数等于17
,但我希望R
自动确定这样的&#34;最优/最大值&#34;相应的箱柜数y
。
假设确定了所需的等间隔/分区数,然后可以使用(至少从我的有效谷歌搜索中)以下内容y
:
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
规范。
答案 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中根据x
和x
分配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