mikebmassey - 1 year ago 144
R Question

# Using CUT and Quartile to generate breaks in R function

Following some great advice from before, I'm now writing my 2nd R function and using a similar logic. However, I'm trying to automate a bit more and may be getting too smart for my own good.

I want to break the clients into quintiles based on the number of orders. Here's my code to do so:

``````# 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
``````

You'll see here that in my sample data, I created 200 observations, yet only 197 are listed via
`table`
. The 3 left off are
`NA`

Now, there are some clientIDs that have an 'NA' for quintile. It seems if they were at the lowest break, in this case, 1, then they were not included in the cut function.

Is there a way to make
`cut`
inclusive of all observations?

Try the following:

``````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
``````

I included `include.lowest=TRUE` in your cut function, which seems to make it work. See `?cut` for more details.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download