R 中的装箱程序?
A binning procedure in R?
我正在努力将以下装箱 "algorithm/procedure" 放入 R code/script 中,这可能类似于用于装箱核密度估计的那些:
假设我们有一些数据:
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
objective 是将 y
分箱成一些相等的 intervals/bins 以便每个分箱包含至少一个来自 x
的观察值(垃圾箱数量 = 不允许空垃圾箱)。对于这个特定的例子,我知道这样的垃圾箱数量等于 17
但我希望 R
自动确定这样的 "optimal/maximum" 垃圾箱数量和相应的垃圾箱 y
。
说确定了所需的等于 intervals/bins 的数量,然后可以使用(至少从我的主动谷歌搜索中)以下内容到 bin y
:
nbins<-cut(y, 17) # binning
哪个做得很好,因为它完全按照我想要的方式拆分 y
,但是如何确定每个 bin 的中心(也许使用 median()
?)以及 x
哪个落入每个垃圾箱?
有一个有趣的包 binr
,功能非常好,但是,它似乎并没有提供我正在寻找的东西。如果有任何提示、提示、建议,我将不胜感激 ...
EDIT: an example of a code with which I ended up with for my calculations.
首先,我想特别感谢@missuse 的帮助、努力和投入。其次,我想为我对某些 base
R 函数的无知(希望是由于缺乏 R 和一般编程经验)表示歉意。
我用@missuse为我的计算开发的代码进行了改造和试验,然而,遗漏x
的问题不断出现,并且经常需要针对不同的数据集进行手动调整。特别是,当我试验由我的数据样本分位数确定的断点时。另外 cut
函数在我看来似乎相当敏感(注意:由于我的目标、数据等原因,这可能是相当主观的)。因此,前几天厌倦了不断调整和为各种 R 函数执行 help()
命令,hist()
来拯救我并解决了几乎所有的装箱问题。所以下面是非常简单的说明,以确定有多少 x
落入每个 bin 以及如何确定每个 bin 的 bin 中心:
hist(x, breaks=c(-5:5), plot=FALSE)$counts # for bin counts
hist(x, breaks=c(-5,5), plot=FALSE)$mids # for bin centers
以上我假设 select 需要休息,您可以根据需要的方式构建基于 cut
函数的函数,并相应地切割网格以进行估计。下面的@missuse 为使用 cut
设置中断提供了良好的基础,只需确保您的数据跨越 hist()
中的 breaks
规范。
可能是这样的:
数据:
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]
中
并且实际上接近 bin 截止值。
这是因为 y
四舍五入到两位小数。例如,如果我们将一个序列分箱:0.01、0.02、0.03 和 0.04,并将其分成 2 个分箱,以 0.025 的比例拆分数据,我们将得到分箱 1:0.01 - 0.02 和分箱 2:0.03 - 0.04,如果我们随后尝试要分配 0.01 - 0.04 范围内的一些随机 x
值,仅基于 bin 中存在的 y
值,我们不会分配 0.02 - 0.03 范围内的任何值 - 因此缺少值。
一个可能的解决方案是将 x
舍入为 2,因为您已经将 seq
舍入为 2。或者用 y
值四舍五入到 4 - 6 位小数和相应地舍入 x
。或者不是根据 bin i 中的 min(yi)
和 max(yi)
分配 x
,而是将 min(yi) <= x
替换为 max(yi-1) < x
(bin i-1 中的 max(yi)),并将 x <= max(yi)
替换为 x < min(yi+1)
。
这是最简单的解决方案,x 保留 2 位小数。
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))
}
)
至少可以解决缺少 x 个元素的问题
优化问题的解也是一样
which(unlist(p))
,只有前4个满足规则,所以3,4,5,6
我正在努力将以下装箱 "algorithm/procedure" 放入 R code/script 中,这可能类似于用于装箱核密度估计的那些:
假设我们有一些数据:
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
objective 是将
y
分箱成一些相等的 intervals/bins 以便每个分箱包含至少一个来自x
的观察值(垃圾箱数量 = 不允许空垃圾箱)。对于这个特定的例子,我知道这样的垃圾箱数量等于17
但我希望R
自动确定这样的 "optimal/maximum" 垃圾箱数量和相应的垃圾箱y
。说确定了所需的等于 intervals/bins 的数量,然后可以使用(至少从我的主动谷歌搜索中)以下内容到 bin
y
:
nbins<-cut(y, 17) # binning
哪个做得很好,因为它完全按照我想要的方式拆分 y
,但是如何确定每个 bin 的中心(也许使用 median()
?)以及 x
哪个落入每个垃圾箱?
有一个有趣的包 binr
,功能非常好,但是,它似乎并没有提供我正在寻找的东西。如果有任何提示、提示、建议,我将不胜感激 ...
EDIT: an example of a code with which I ended up with for my calculations.
首先,我想特别感谢@missuse 的帮助、努力和投入。其次,我想为我对某些 base
R 函数的无知(希望是由于缺乏 R 和一般编程经验)表示歉意。
我用@missuse为我的计算开发的代码进行了改造和试验,然而,遗漏x
的问题不断出现,并且经常需要针对不同的数据集进行手动调整。特别是,当我试验由我的数据样本分位数确定的断点时。另外 cut
函数在我看来似乎相当敏感(注意:由于我的目标、数据等原因,这可能是相当主观的)。因此,前几天厌倦了不断调整和为各种 R 函数执行 help()
命令,hist()
来拯救我并解决了几乎所有的装箱问题。所以下面是非常简单的说明,以确定有多少 x
落入每个 bin 以及如何确定每个 bin 的 bin 中心:
hist(x, breaks=c(-5:5), plot=FALSE)$counts # for bin counts
hist(x, breaks=c(-5,5), plot=FALSE)$mids # for bin centers
以上我假设 select 需要休息,您可以根据需要的方式构建基于 cut
函数的函数,并相应地切割网格以进行估计。下面的@missuse 为使用 cut
设置中断提供了良好的基础,只需确保您的数据跨越 hist()
中的 breaks
规范。
可能是这样的:
数据:
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]
中
并且实际上接近 bin 截止值。
这是因为 y
四舍五入到两位小数。例如,如果我们将一个序列分箱:0.01、0.02、0.03 和 0.04,并将其分成 2 个分箱,以 0.025 的比例拆分数据,我们将得到分箱 1:0.01 - 0.02 和分箱 2:0.03 - 0.04,如果我们随后尝试要分配 0.01 - 0.04 范围内的一些随机 x
值,仅基于 bin 中存在的 y
值,我们不会分配 0.02 - 0.03 范围内的任何值 - 因此缺少值。
一个可能的解决方案是将 x
舍入为 2,因为您已经将 seq
舍入为 2。或者用 y
值四舍五入到 4 - 6 位小数和相应地舍入 x
。或者不是根据 bin i 中的 min(yi)
和 max(yi)
分配 x
,而是将 min(yi) <= x
替换为 max(yi-1) < x
(bin i-1 中的 max(yi)),并将 x <= max(yi)
替换为 x < min(yi+1)
。
这是最简单的解决方案,x 保留 2 位小数。
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))
}
)
至少可以解决缺少 x 个元素的问题
优化问题的解也是一样
which(unlist(p))
,只有前4个满足规则,所以3,4,5,6