data.table,过滤 >= 每组中位数并保留两个最低
data.table, filter >= median per group and keep two lowest
情况与目标
我有一个大 table 看起来像(简化):
|MainCat |SubCat | Value|
|:-------|:------|-----:|
|A |Y | 50|
|A |Z | 60|
|A |ZZZZ | 80|
|A |XX | 90|
|A |X | 100|
|B |XYXY | 15|
|B |XXX | 50|
|B |YY | 60|
|B |ZZZ | 150|
|B |ZZ | 400|
现在我想过滤每个组 (MainCat
) 并只保留比中位数 equal/greater 的两个最低值 (Value
):
|MainCat |SubCat | Value|Comment |
|:-------|:------|-----:|:---------------------|
|A |Y | 50|- |
|A |Z | 60|- |
|A |ZZZZ | 80|Median, First to keep |
|A |XX | 90|Second to keep |
|A |X | 100|- |
|B |XYXY | 15|- |
|B |XXX | 50|- |
|B |YY | 60|Median, First to keep |
|B |ZZZ | 150|Second to keep |
|B |ZZ | 400|- |
预期结果:
|MainCat |SubCat | Value|
|:-------|:------|-----:|
|A |ZZZZ | 80|
|A |XX | 90|
|B |YY | 60|
|B |ZZZ | 150|
我的(失败)尝试
我试过 df2[Value >= df2[MainCat==MainCat, median(Value, na.rm=TRUE)]]
但这计算了所有值的中位数,没有分组。有人可以帮忙吗?由于性能是关键,如果可能的话,我更喜欢 data.table
解决方案。非常感谢。
MWE
基础数据:
df2 = structure(list(MainCat = c("A", "A", "A", "A", "A", "B", "B",
"B", "B", "B"), SubCat = c("Y", "Z", "ZZZZ", "XX", "X", "XYXY",
"XXX", "YY", "ZZZ", "ZZ"), Value = c(50, 60, 80, 90, 100, 15,
50, 60, 150, 400)), row.names = c(NA, -10L), class = c("data.table",
"data.frame"))
结果:
data.table(MainCat=c("A","A","B","B"),
SubCat=c("ZZZZ", "XX", "YY", "ZZZ"),
Value=c(80,90,60,150))
按'MainCat'进行分组,在使用median
'Value'创建逻辑表达式后获取行索引(.I
),提取索引($V1
), 数据子集, order
由 'MainCat', 'Value', 得到前两行 head
, 按 'MainCat'[=17 分组=]
library(data.table)
df2[df2[, .I[Value >= median(Value, na.rm = TRUE)],.(MainCat)]$V1
][order(MainCat, Value), head(.SD, 2), MainCat]
-输出
MainCat SubCat Value
<char> <char> <num>
1: A ZZZZ 80
2: A XX 90
3: B YY 60
4: B ZZZ 150
情况与目标
我有一个大 table 看起来像(简化):
|MainCat |SubCat | Value|
|:-------|:------|-----:|
|A |Y | 50|
|A |Z | 60|
|A |ZZZZ | 80|
|A |XX | 90|
|A |X | 100|
|B |XYXY | 15|
|B |XXX | 50|
|B |YY | 60|
|B |ZZZ | 150|
|B |ZZ | 400|
现在我想过滤每个组 (MainCat
) 并只保留比中位数 equal/greater 的两个最低值 (Value
):
|MainCat |SubCat | Value|Comment |
|:-------|:------|-----:|:---------------------|
|A |Y | 50|- |
|A |Z | 60|- |
|A |ZZZZ | 80|Median, First to keep |
|A |XX | 90|Second to keep |
|A |X | 100|- |
|B |XYXY | 15|- |
|B |XXX | 50|- |
|B |YY | 60|Median, First to keep |
|B |ZZZ | 150|Second to keep |
|B |ZZ | 400|- |
预期结果:
|MainCat |SubCat | Value|
|:-------|:------|-----:|
|A |ZZZZ | 80|
|A |XX | 90|
|B |YY | 60|
|B |ZZZ | 150|
我的(失败)尝试
我试过 df2[Value >= df2[MainCat==MainCat, median(Value, na.rm=TRUE)]]
但这计算了所有值的中位数,没有分组。有人可以帮忙吗?由于性能是关键,如果可能的话,我更喜欢 data.table
解决方案。非常感谢。
MWE
基础数据:
df2 = structure(list(MainCat = c("A", "A", "A", "A", "A", "B", "B",
"B", "B", "B"), SubCat = c("Y", "Z", "ZZZZ", "XX", "X", "XYXY",
"XXX", "YY", "ZZZ", "ZZ"), Value = c(50, 60, 80, 90, 100, 15,
50, 60, 150, 400)), row.names = c(NA, -10L), class = c("data.table",
"data.frame"))
结果:
data.table(MainCat=c("A","A","B","B"),
SubCat=c("ZZZZ", "XX", "YY", "ZZZ"),
Value=c(80,90,60,150))
按'MainCat'进行分组,在使用median
'Value'创建逻辑表达式后获取行索引(.I
),提取索引($V1
), 数据子集, order
由 'MainCat', 'Value', 得到前两行 head
, 按 'MainCat'[=17 分组=]
library(data.table)
df2[df2[, .I[Value >= median(Value, na.rm = TRUE)],.(MainCat)]$V1
][order(MainCat, Value), head(.SD, 2), MainCat]
-输出
MainCat SubCat Value
<char> <char> <num>
1: A ZZZZ 80
2: A XX 90
3: B YY 60
4: B ZZZ 150