在 data.table 中按组划分的分位数

Posted

技术标签:

【中文标题】在 data.table 中按组划分的分位数【英文标题】:quantile cut by group in data.table 【发布时间】:2017-08-14 08:52:48 【问题描述】:

我想对每组进行分位数切割(切割成 n 个点数相等的箱)

qcut = function(x, n) 
  quantiles = seq(0, 1, length.out = n+1)
  cutpoints = unname(quantile(x, quantiles, na.rm = TRUE))
  cut(x, cutpoints, include.lowest = TRUE)


library(data.table)
dt = data.table(A = 1:10, B = c(1,1,1,1,1,2,2,2,2,2))
dt[, bin := qcut(A, 3)]
dt[, bin2 := qcut(A, 3), by = B]

dt
A     B    bin        bin2
 1:  1 1  [1,4]    [6,7.33]
 2:  2 1  [1,4]    [6,7.33]
 3:  3 1  [1,4] (7.33,8.67]
 4:  4 1  [1,4]   (8.67,10]
 5:  5 1  (4,7]   (8.67,10]
 6:  6 2  (4,7]    [6,7.33]
 7:  7 2  (4,7]    [6,7.33]
 8:  8 2 (7,10] (7.33,8.67]
 9:  9 2 (7,10]   (8.67,10]
10: 10 2 (7,10]   (8.67,10]

这里没有分组的剪辑是正确的——数据在 bin 中。但是分组的结果是错误的。

我该如何解决这个问题?

【问题讨论】:

dt[, qcut(A, 3), by = B] 可以工作 【参考方案1】:

这是处理因子的错误。请检查它是否已知(或在开发版本中已修复),否则将其报告给 data.table 错误跟踪器。

qcut = function(x, n) 
  quantiles = seq(0, 1, length.out = n+1)
  cutpoints = unname(quantile(x, quantiles, na.rm = TRUE))
  as.character(cut(x, cutpoints, include.lowest = TRUE))


dt[, bin2 := qcut(A, 3), by = B]
#     A B    bin        bin2
# 1:  1 1  [1,4]    [1,2.33]
# 2:  2 1  [1,4]    [1,2.33]
# 3:  3 1  [1,4] (2.33,3.67]
# 4:  4 1  [1,4]    (3.67,5]
# 5:  5 1  (4,7]    (3.67,5]
# 6:  6 2  (4,7]    [6,7.33]
# 7:  7 2  (4,7]    [6,7.33]
# 8:  8 2 (7,10] (7.33,8.67]
# 9:  9 2 (7,10]   (8.67,10]
#10: 10 2 (7,10]   (8.67,10]

【讨论】:

在不改变函数的情况下,dt[, bin2 := as.character(qcut(A, 3)), by=B] 也可以工作,如果尝试将其转换为因子 (dt[, bin2 := as.factor(as.character(qcut(A, 3))), by=B]) 会引发错误... 是的,如果你定义每个组的因素,最后一列(组合组)将只采用第 1 组的属性(如级别),我认为github.com/Rdatatable/data.table/issues/967

以上是关于在 data.table 中按组划分的分位数的主要内容,如果未能解决你的问题,请参考以下文章

在单个 R data.table 中按组有效地定位

聊聊python的分位数

使用 SciPy 的分位数-分位数图

python求beta分布的分位数

如何理解概率分布的分位数和上侧分位数?

如何计算基于组的分位数?