在 R data.table 中具有外部指定四分位数断点的四分位数排序器
Quartile sorter with externally specified quartile breakpoints in R data.table
我想根据变量 "varbl" 将观察结果分类为四分位数。由于我的数据非常大 (2Gb),我正在尝试通过 data.table 来实现它。问题是我需要使用特定于组的外部四分位数。组变量为 "prd" 或 "prd1".
我的数据和断点如下:
data <- data.table(id = c(1,2,3,4,5,1,2,3,4,5), prd1 = c(1,1,1,1,1,2,2,2,2,2), varbl = c(-1.6, -0.7, 0.1, 1.2, -0.5, -0.8, 0.4, 1.2, 1.9, 4))
bks <- data.table(prd=c(1,2), br0 = c(-5,-5), br1=c(-1,0), br2=c(0, 0.5), br3=c(1, 3), br4=c(5,5))
> data
id prd1 varbl
1: 1 1 -1.6
2: 2 1 -0.7
3: 3 1 0.1
4: 4 1 1.2
5: 5 1 -0.5
6: 1 2 -0.8
7: 2 2 0.4
8: 3 2 1.2
9: 4 2 1.9
10: 5 2 4.0
> bks
prd br0 br1 br2 br3 br4
1: 1 -5 -1 0.0 1 5
2: 2 -5 0 0.5 3 5
期望的输出是:
> output
id prd1 varbl ntile
1: 1 1 -1.6 1
2: 2 1 -0.7 2
3: 3 1 0.1 3
4: 4 1 1.2 4
5: 5 1 -0.5 2
6: 1 2 -0.8 1
7: 2 2 0.4 2
8: 3 2 1.2 3
9: 4 2 1.9 3
10: 5 2 4.0 4
我尝试了以下代码,但它失败了,因为我无法在与来自数据的当前 prd1 相同的 prd 上对 bks 进行子集化:
data[, ntile := cut(varbl, breaks = bks[prd==prd1], include.lowest=TRUE, labels = 1:4)]
作为另一种尝试,我尝试先加入数据和 bks(我不想这样做,因为它会将数据的大小从 2Gb 增加到 4Gb)
然后将观察结果分类为分位数。它失败了,因为我不明白如何使用列名为每一行构造一个断点向量。 None 次尝试成功。
setnames(data, "prd1", "prd")
data <- data[bks, on="prd", nomatch=0]
data[, ntile := cut(varbl, breaks = .(br0, br1, br2, br3, br4), include.lowest=TRUE, labels=1:4)]
data[, ntile := cut(varbl, breaks = colnames(bks)[-1], include.lowest=TRUE, labels=1:4)]
data[, ntile := cut(varbl, breaks = c("br0", "br1", "br2", "br3", "br4"), include.lowest=TRUE, labels=1:4)]
稍微重新排列 bks
意味着您可以将其作为一个连接来执行此操作:
bks <- bks[, data.frame(embed(unlist(.SD),2)[,2:1]), by=prd]
bks[, grp := seq_len(.N), by=prd]
# prd X1 X2 grp
#1: 1 -5.0 -1.0 1
#2: 1 -1.0 0.0 2
#3: 1 0.0 1.0 3
#4: 1 1.0 5.0 4
#5: 2 -5.0 0.0 1
#6: 2 0.0 0.5 2
#7: 2 0.5 3.0 3
#8: 2 3.0 5.0 4
data[bks, on=c("prd1"="prd","varbl>=X1","varbl<X2"), grp := i.grp]
# id prd1 varbl grp
# 1: 1 1 -1.6 1
# 2: 2 1 -0.7 2
# 3: 3 1 0.1 3
# 4: 4 1 1.2 4
# 5: 5 1 -0.5 2
# 6: 1 2 -0.8 1
# 7: 2 2 0.4 2
# 8: 3 2 1.2 3
# 9: 4 2 1.9 3
#10: 5 2 4.0 4
我想根据变量 "varbl" 将观察结果分类为四分位数。由于我的数据非常大 (2Gb),我正在尝试通过 data.table 来实现它。问题是我需要使用特定于组的外部四分位数。组变量为 "prd" 或 "prd1".
我的数据和断点如下:
data <- data.table(id = c(1,2,3,4,5,1,2,3,4,5), prd1 = c(1,1,1,1,1,2,2,2,2,2), varbl = c(-1.6, -0.7, 0.1, 1.2, -0.5, -0.8, 0.4, 1.2, 1.9, 4))
bks <- data.table(prd=c(1,2), br0 = c(-5,-5), br1=c(-1,0), br2=c(0, 0.5), br3=c(1, 3), br4=c(5,5))
> data
id prd1 varbl
1: 1 1 -1.6
2: 2 1 -0.7
3: 3 1 0.1
4: 4 1 1.2
5: 5 1 -0.5
6: 1 2 -0.8
7: 2 2 0.4
8: 3 2 1.2
9: 4 2 1.9
10: 5 2 4.0
> bks
prd br0 br1 br2 br3 br4
1: 1 -5 -1 0.0 1 5
2: 2 -5 0 0.5 3 5
期望的输出是:
> output
id prd1 varbl ntile
1: 1 1 -1.6 1
2: 2 1 -0.7 2
3: 3 1 0.1 3
4: 4 1 1.2 4
5: 5 1 -0.5 2
6: 1 2 -0.8 1
7: 2 2 0.4 2
8: 3 2 1.2 3
9: 4 2 1.9 3
10: 5 2 4.0 4
我尝试了以下代码,但它失败了,因为我无法在与来自数据的当前 prd1 相同的 prd 上对 bks 进行子集化:
data[, ntile := cut(varbl, breaks = bks[prd==prd1], include.lowest=TRUE, labels = 1:4)]
作为另一种尝试,我尝试先加入数据和 bks(我不想这样做,因为它会将数据的大小从 2Gb 增加到 4Gb) 然后将观察结果分类为分位数。它失败了,因为我不明白如何使用列名为每一行构造一个断点向量。 None 次尝试成功。
setnames(data, "prd1", "prd")
data <- data[bks, on="prd", nomatch=0]
data[, ntile := cut(varbl, breaks = .(br0, br1, br2, br3, br4), include.lowest=TRUE, labels=1:4)]
data[, ntile := cut(varbl, breaks = colnames(bks)[-1], include.lowest=TRUE, labels=1:4)]
data[, ntile := cut(varbl, breaks = c("br0", "br1", "br2", "br3", "br4"), include.lowest=TRUE, labels=1:4)]
稍微重新排列 bks
意味着您可以将其作为一个连接来执行此操作:
bks <- bks[, data.frame(embed(unlist(.SD),2)[,2:1]), by=prd]
bks[, grp := seq_len(.N), by=prd]
# prd X1 X2 grp
#1: 1 -5.0 -1.0 1
#2: 1 -1.0 0.0 2
#3: 1 0.0 1.0 3
#4: 1 1.0 5.0 4
#5: 2 -5.0 0.0 1
#6: 2 0.0 0.5 2
#7: 2 0.5 3.0 3
#8: 2 3.0 5.0 4
data[bks, on=c("prd1"="prd","varbl>=X1","varbl<X2"), grp := i.grp]
# id prd1 varbl grp
# 1: 1 1 -1.6 1
# 2: 2 1 -0.7 2
# 3: 3 1 0.1 3
# 4: 4 1 1.2 4
# 5: 5 1 -0.5 2
# 6: 1 2 -0.8 1
# 7: 2 2 0.4 2
# 8: 3 2 1.2 3
# 9: 4 2 1.9 3
#10: 5 2 4.0 4