【问题标题】:How to sort vector into bins in R?如何将向量分类到R中的bin中?
【发布时间】:2020-09-17 15:52:29
【问题描述】:

我有一个向量,它由可以取 1 到 100 之间任何值的数字组成。 我想将该向量分类到一定大小的箱中。

我的逻辑:

1.) 将范围(在本例中为 1:100)除以您想要的 bin 数量(在本例中假设为 10)

结果:(1, 10.9], 10.9,20.8], (20.8,30.7], (30.7,40.6], (40.6,50.5], (50.5,60.4], (60.4,70.3], (70.3,80.2) ], (80.2,90.1], (90.1,100]

2.) 然后对我的向量进行排序


我发现了一个方便的功能,几乎一举就能完成所有这些工作:cut()。这是我的代码:

> table(cut(vector, breaks = 10))

(0.959,10.9]  (10.9,20.8]  (20.8,30.7]  (30.7,40.5]  (40.5,50.4]  (50.4,60.3]  (60.3,70.1]    (70.1,80]    (80,89.9]  (89.9,99.8] 
         175          171          117          103           82           67           54           46           39           31 

不幸的是,间隔与我们根据可能范围 (1:100) 计算的区间不同。所以我尝试通过将该范围添加到向量中来解决这个问题:

> table(cut(c(1,100,vector), breaks = 10))

(0.901,10.9]  (10.9,20.8]  (20.8,30.7]  (30.7,40.6]  (40.6,50.5]  (50.5,60.4]  (60.4,70.3]  (70.3,80.2]  (80.2,90.1]   (90.1,100] 
         176          171          117          104           82           66           54           48           38           31

除了最左边的区间由于某种原因从 0.901 开始之外,这几乎可以完美运行。


我的问题:

1.) 有没有办法做到这一点(使用 cut 或其他函数/包)而无需插入人工数据点来获得指定的 bin 范围?

2.) 如果不是,为什么较低的 bin 从 0.901 开始而不是 1?

【问题讨论】:

  • 您可以将breaks 指定为自定义值的向量。这样做的原因是基于代码breaks <- seq.int(rx[1L] - dx/1000, rx[2L] + dx/1000,,当中断的长度为1时
  • 试试cut(vector, breaks = 0:10 * 10)
  • 嗨艾伦,我有兴趣将范围 1:100,而不是 0:100,分成 10 个箱。否则,是的,这会起作用。

标签: r


【解决方案1】:

根据您对@Allan Cameron 的回复,我了解您想将vector 分成 10 个相同大小的箱子。但是,当您在 cut() 函数中定义此中断数时,该函数计算的间隔大小在各个组中是不同的。正如@akrun 悲伤的那样,这是因为函数在这种情况下使用的微积分方法您只定义了中断的数量。

我不知道是否有办法在函数中避免这种情况。但我认为如果你按照@Gregor Thomas 的建议定义你想要的垃圾箱会更容易。以下是我将如何满足您的愿望的示例:

vec <- sample(1:100, size = 500, replace = T)

# Here I suppose that you want to divide the data in
# intervals of the same length
breaks <- seq(min(vec), max(vec), by = 9.9)

cut(vec, breaks = breaks)

其他选项,将是来自ggplot2 包的cut_interval() 函数,它将向量分成n 组,长度相同。

library(ggplot2)

cut_interval(vec, n = 10)

【讨论】:

    【解决方案2】:

    为什么较低的 bin 从 0.901 而不是 1 开始?

    答案是?cut帮助页面的详细信息部分的第一位:

    breaks指定为单个数字时,将数据的范围划分为等长的断点,然后将外部限制移开范围的0.1%,以确保极值都落在在休息时间间隔内。

    0.1% 的调整是您的下限为 0.901 的原因 --- 上限未调整,因为它是封闭的 ],而不是开放的 ) 区间。

    如果您想使用其他中断,您可以根据需要指定确切的中断。也许是这样:

    my_breaks = seq(1, 100, length.out = 11) ## for n bins, you need n+1 breaks
    my_breaks
    # [1]   1.0  10.9  20.8  30.7  40.6  50.5  60.4  70.3  80.2  90.1 100.0
    
    cut(vector, breaks = my_breaks, include.lowest = TRUE)
    

    但我实际上认为艾伦对0:10 * 10 的建议可能是您真正想要的。我不会太快地忽略它:

    table(cut(1:100, breaks = 0:10*10))
    
    #   (0,10]  (10,20]  (20,30]  (30,40]  (40,50]  (50,60]  (60,70]  (70,80]  (80,90] (90,100] 
    #       10       10       10       10       10       10       10       10       10       10
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-25
      • 2015-03-31
      • 1970-01-01
      • 2020-04-21
      • 1970-01-01
      • 2014-02-25
      • 2021-04-17
      • 1970-01-01
      相关资源
      最近更新 更多