web-dev-qa-db-fra.com

Utilisation de CUT et Quartile pour générer des ruptures dans la fonction R

Après quelques bons conseils d'avant , j'écris maintenant ma 2ème fonction R et j'utilise une logique similaire. Cependant, j'essaie d'automatiser un peu plus et je deviens peut-être trop intelligent pour mon propre bien.

Je veux diviser les clients en quintiles en fonction du nombre de commandes. Voici mon code pour le faire:

# sample data
clientID <- round(runif(200,min=2000, max=3000),0)
orders <- round(runif(200,min=1, max=50),0)

df <- df <- data.frame(cbind(clientID,orders))

#function to break them into quintiles
ApplyQuintiles <- function(x) {
  cut(x, breaks=c(quantile(df$orders, probs = seq(0, 1, by = 0.20))), 
      labels=c("0-20","20-40","40-60","60-80","80-100"))
}

#Add the quintile to the dataframe
df$Quintile <- sapply(df$orders, ApplyQuintiles)

table(df$Quintile)

0-20   20-40   40-60    60-80   80-100 
40     39      44       38      36

Vous verrez ici que dans mes exemples de données, j'ai créé 200 observations, mais seulement 197 sont répertoriées via table. Les 3 restants sont NA

Maintenant, il y a quelques ID client qui ont un "NA" pour le quintile. Il semble que s'ils étaient à la pause la plus basse, dans ce cas, 1, alors ils n'étaient pas inclus dans la fonction de coupe.

Existe-t-il un moyen de rendre cut inclusif de toutes les observations?

22
mikebmassey

Essayez ce qui suit:

set.seed(700)

clientID <- round(runif(200,min=2000, max=3000),0)
orders <- round(runif(200,min=1, max=50),0)

df <- df <- data.frame(cbind(clientID,orders))

ApplyQuintiles <- function(x) {
  cut(x, breaks=c(quantile(df$orders, probs = seq(0, 1, by = 0.20))), 
      labels=c("0-20","20-40","40-60","60-80","80-100"), include.lowest=TRUE)
}
df$Quintile <- sapply(df$orders, ApplyQuintiles)
table(df$Quintile)

0-20  20-40  40-60  60-80 80-100 
  40     41     39     40     40 

J'ai inclus include.lowest=TRUE dans votre fonction de coupe, ce qui semble la faire fonctionner. Voir ?cut pour plus de détails.

22
Edward

Il y a aussi cut2 dans le vénérable paquet Hmisc. Il fait des coupes quantiles.

De l'aide:

Les fonctions comme couper mais les extrémités gauche sont inclusives et les étiquettes sont de la forme [inférieure, supérieure), sauf que le dernier intervalle est [inférieur, supérieur]. Si des coupes sont données, s'assurera par défaut que les coupes incluent toute la plage de x. De plus, si les coupes ne sont pas données, coupera x en groupes de quantiles (g donnés) ou en groupes avec un nombre minimum donné d'observations (m). Alors que cut crée un objet catégorie, cut2 crée un objet facteur.

6
Owen

Vous pouvez très facilement accomplir cela automatiquement avec la méthode content dans la fonction bin dans le package OneR :

library(OneR)
set.seed(700)

clientID <- round(runif(200, min = 2000, max = 3000), 0)
orders <- round(runif(200, min = 1, max = 50), 0)
df <- data.frame(cbind(clientID, orders))

df$Quintiles <- bin(df$orders, method = "content")
table(df$Quintile)
## 
## (0.952,9.8]    (9.8,19]   (19,31.4] (31.4,38.2]   (38.2,49] 
##          40          41          39          40          40

(Divulgation complète: je suis l'auteur de ce paquet)

3
vonjd

J'utilise une fonction similaire pour mes données et je suis inquiet parce que mes bacs de quintile ont des nombres d'observation différents: est-ce correct? Merci!

jobs02.vq <- cut(meaneduc02v, breaks=c(quantile(meaneduc02v,  probs = seq(0,        1, by=0.20), 
                          na.rm=TRUE, names=TRUE, include.lowest=TRUE, right = TRUE, 
                          labels=c("1","2","3","4","5")))) # makes quintiles

Et la sortie que j'obtiens est:

 table(jobs02.vq, useNA='ifany')
 jobs02.vq
 [1.00,2.00) [2.00,2.51) [2.51,3.34) [3.34,4.45) [4.45,5.33]        <NA> 
     82          54          69          64          67         123 
2
Paula