数据是这样的:
temp <- data.frame(type = c("a","b","c","d"), value=runif(100, 10, 2380))
temp <- as.data.table(temp)
# type value
# 1: a 2250.33013
# 2: b 1271.71251
# 3: c 2299.45486
# 4: d 807.30089
# 5: a 31.32157
我想计算每种类型的四分位数,然后将类定义为每个分区的class1,2,3,4。
我的目标是在不同类型之间均匀分配类值。
我的第一个快速方法就是这样,
a <- temp[type == "a"]
b <- temp[type == "b"]
c <- temp[type == "c"]
d <- temp[type == "d"]
quantile(a$value)
quantile(b$value)
quantile(c$value)
quantile(d$value)
dt <- temp[, quantile := quantile(value), by = type]
然后创建dt$class <- ifelse(...)
但这似乎是绕道来解决这个问题的方法。我觉得我可以在这里使用各种技术,但还没有找到相关的科目。
我理想的结果应该是这样的(忽略这个数字)
# type value quantile class
# 1: a 2250.33013 31.32157 class1
# 2: b 1271.71251 112.83298 class2
# 3: c 2299.45486 33.67312 class3
# 4: d 807.30089 40.06302 class4
# 5: a 31.32157 535.78510 class1
# 6: b 815.11432 808.63388 class2
# 7: c 1341.02811 1128.15997 class3
# 8: d 964.20982 650.42241 class4
# 9: a 2208.44555 1290.29102 class1
# 10: b 1167.64278 1369.88565 class2
# 11: c 349.35402 1526.66226 class3
# 12: d 643.73551 1073.49396 class4
这样,最终,我会在整个类型中均匀分布类。请分享我的想法,以更聪明的方式做到这一点。谢谢!
答案 0 :(得分:3)
您可以使用dplyr
按类型分组,然后使用ntile
在群组中排名。无需将temp
转换为数据表。
library(dplyr)
temp <- data.frame(type = c("a","b","c","d"),
value=runif(100, 10, 2380))
temp %>%
group_by(type) %>%
mutate(class = ntile(value, 4)) %>%
ungroup()
# A tibble: 100 × 3
type value class
<fctr> <dbl> <int>
1 a 347.7757 1
2 b 789.0118 2
3 c 952.6286 2
4 d 826.3092 1
5 a 378.6079 1
6 b 136.0738 1
7 c 1742.9738 4
8 d 1788.1156 3
9 a 1133.6740 3
10 b 2283.8092 4
# ... with 90 more rows
答案 1 :(得分:2)
要实现您的目标,您可以使用cut
功能,如下所示:
temp[, quant := quantile(value), by = type
][, clas := cut(value,
unique(quant),
labels = paste0('class',1:4),
include.lowest = TRUE),
by = type]
给你:
> temp
type value quant clas
1: a 2078.94314 129.56675 class4
2: b 1360.65024 107.40551 class2
3: c 1753.82409 91.92594 class4
4: d 1384.85250 149.01646 class4
5: a 653.64766 456.96086 class2
6: b 1925.33187 565.15271 class4
....
95: c 1460.56660 1676.58185 class3
96: d 673.59436 1314.27001 class2
97: a 1147.94976 2203.73669 class3
98: b 648.93761 2317.71071 class2
99: c 1341.69222 2328.16911 class2
100: d 149.01646 2268.54346 class1
如果您只对clas
- 变量感兴趣,还可以:
temp[, clas := cut(value,
quantile(value),
labels = paste0('class',1:4),
include.lowest = TRUE),
by = type]
旁注:在使用随机值生成器(如sample
,runif
或rnorm
)提供样本数据时,最好使用set.seed()
。此外:最好不要让变量与函数同名(因此在我的答案中使用quant
和clas
)。
使用过的数据:
set.seed(26042017)
temp <- data.table(type = c("a","b","c","d"), value = runif(100, 10, 2380))