首页 文章

R:将加权列拆分为等大小的桶

提问于
浏览
0

我想使用类似dplyr的 cut_number 之类的东西将列拆分成具有大致相同数量的观察值的桶,其中我的数据集是紧凑形式,其中每行具有权重(观察数) .

示例数据框:

df <- data.frame(
    x=c(18,17,18.5,20,20.5,24,24.4,18.3,31,34,39,20,19,34,23),
    weight=c(1,10,3,6,19,20,34,66,2,3,1,6,9,15,21)
)

如果每行有一次x观察,我只需使用 df$bucket <- cut_number(df$x,3)x 分段为3个桶,观察次数大致相同 . 但是,我如何考虑每一行用一些观察值加权的事实?我想避免将每一行拆分为 weight 行,因为原始数据帧已经有数百万行 .

2 回答

  • 1

    根据评论,我认为这可能是您正在寻找的区间集 . 对它的一般取消的道歉:

    dfTest <- data.frame(x=1:6, weight=c(1,1,1,1,4,1))
    
    f <- function(df, n) {
      interval <- round(sum(df$weight) / n)
      buckets <- vector(mode="integer", length(nrow(df)))
      bucketNum <- 1
      count <- 0
      for (i in 1:nrow(df)) {
        count <- count + df$weight[i]
        buckets[i] <- bucketNum
        if (count >= interval) {
          bucketNum <- bucketNum + 1
          count <- 0
        }
      }
      return(buckets)
    }
    

    运行此函数会对项目执行如下操作:

    dfTest$bucket <- f(dfTest, 3)
    
    #    x weight bucket
    #  1 1      1      1
    #  2 2      1      1
    #  3 3      1      1
    #  4 4      1      2
    #  5 5      4      2
    #  6 6      1      3
    

    对于你的例子:

    df$bucket <- f(df, 3)
    #        x weight bucket
    #  1  18.0      1      1
    #  2  17.0     10      1
    #  3  18.5      3      1
    #  4  20.0      6      1
    #  5  20.5     19      1
    #  6  24.0     20      1
    #  7  24.4     34      1
    #  8  18.3     66      2
    #  9  31.0      2      2
    #  10 34.0      3      2
    #  11 39.0      1      2
    #  12 20.0      6      3
    #  13 19.0      9      3
    #  14 34.0     15      3
    #  15 23.0     21      3
    
  • 1

    这是另一种方法,基于我的假设你总共有x1 * weight1 x2 * weight2 .....观察 . 此外,每个“独特”观察只能在一个桶中 . 该方法使用排序和权重的累积总和来创建桶 .

    #sort data
    df <- df[order(df$x),]
    
    #calculate cumulative weights (this is why we sort)
    df$cumulative_weight <- cumsum(df$weight)
    
    #create bucket by cumulative weight
    n_buckets <- 3
    df$bucket <- cut(df$cumulative_weight, n_buckets)
    
    #check: calculate total number of observations per bucket   
    
    
    > aggregate(weight~bucket,FUN=sum, data=df)
           bucket weight
    1 (9.79,78.7]     77
    2  (78.7,147]     64
    3   (147,216]     75
    

相关问题