2017-04-26 7 views
1

Die Daten sind wie folgt definieren:pro Kategorie ermitteln und Klassennamen entsprechend

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 

Ich mag würde Quartil pro Typ berechnen, dann wird die Klasse als class1,2,3,4 pro Division definieren.

Mein Ziel ist es, Klassenwert gleichmäßig auf verschiedene Typen zu verteilen.

Mein erster schneller Ansatz war wie diese,

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] 

Und dann dt$class <- ifelse(...)

erstellen Aber das scheint wie ein Umweg Weg, um dieses Problem zu lösen. Ich habe das Gefühl, ich könnte hier Techniken anwenden, aber ich konnte noch nicht verwandte Themen finden.

Mein ideales Ergebnis sollte wie folgt (ignorieren Sie die Zahlen für diese)

# 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 

So dass letztlich sein, würde ich über die Art gleichmäßig verteilt Klassen haben. Bitte teilen Sie mir Ihre Idee, dies auf intelligentere Weise zu tun. Vielen Dank!

Antwort

2

Um das zu erreichen, was Sie wollen, können Sie die cut Funktion wie folgt:

temp[, quant := quantile(value), by = type 
    ][, clas := cut(value, 
        unique(quant), 
        labels = paste0('class',1:4), 
        include.lowest = TRUE), 
     by = type] 

, die Sie gibt:

> 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 

Wenn Sie in der clas -variable, können Sie auch nur daran interessiert sind tun:

temp[, clas := cut(value, 
        quantile(value), 
        labels = paste0('class',1:4), 
        include.lowest = TRUE), 
    by = type] 

Nebenbei: Bei der Bereitstellung von Beispieldaten mit Zufallswertgeneratoren (wie sample, runif oder rnorm) ist es besser set.seed() zu verwenden. Außerdem: Es ist besser, Ihren Variablen nicht den gleichen Namen wie den Funktionen zu geben (daher die Verwendung von und clas in meiner Antwort).

Gebrauchte Daten:

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

Sie dplyr zu einer Gruppe von Typ verwenden könnten und dann innerhalb von Gruppen ordnen ntile verwenden. Keine Notwendigkeit, temp in eine Datentabelle umzuwandeln.

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 
Verwandte Themen