计算每个类别并相应地定义类名

时间:2017-04-26 05:08:09

标签: r data.table classification stat quantile

数据是这样的:

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

这样,最终,我会在整个类型中均匀分布类。请分享我的想法,以更聪明的方式做到这一点。谢谢!

2 个答案:

答案 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]

旁注:在使用随机值生成器(如samplerunifrnorm)提供样本数据时,最好使用set.seed()。此外:最好不要让变量与函数同名(因此在我的答案中使用quantclas)。

使用过的数据:

set.seed(26042017)
temp <- data.table(type = c("a","b","c","d"), value = runif(100, 10, 2380))