按类别计算并相应地定义 class 名称
Calculate per category and define class name accordingly
数据是这样的:
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
我想计算每个类型的四分位数,然后将 class 定义为每个分区的 class1,2,3,4。
我的目标是在不同类型之间平均分配 class 值。
我的第一个快速方法是这样的,
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
因此,最终我会在整个类型中均匀分布 classes。请与我分享您以更聪明的方式做到这一点的想法。谢谢!
要实现您想要的效果,您可以使用 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))
您可以使用 dplyr
按类型分组,然后使用 ntile
在组内排名。无需将 temp
转换为数据 table.
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
数据是这样的:
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
我想计算每个类型的四分位数,然后将 class 定义为每个分区的 class1,2,3,4。
我的目标是在不同类型之间平均分配 class 值。
我的第一个快速方法是这样的,
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
因此,最终我会在整个类型中均匀分布 classes。请与我分享您以更聪明的方式做到这一点的想法。谢谢!
要实现您想要的效果,您可以使用 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))
您可以使用 dplyr
按类型分组,然后使用 ntile
在组内排名。无需将 temp
转换为数据 table.
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