views:

62

answers:

2

Hi all,

i´d like to assign factors representing quantiles. Thus I need them to be numeric. That´s why I wrote the following function, which is basically the answer to my problem:

qdum <- function(v,q){

qd = quantile(v,1:(q)/q)
v = as.data.frame(v)
v$b = 0
names(v) <- c("a","b")
i=1
for (i in 1:q){

    if(i == 1)
        v$b[ v$a < qd[1]] = 1
    else
        v$b[v$a > qd[i-1] & v$a <= qd[i]] = i
}

all = list(qd,v)
return(all)

    }

you may laugh now :) . The returned list contains a variable that can be used to assign every observation to its corresponding quantile. My question is now: is there a better way (more "native" or "core") to do it? I know about quantcut (from the gtools package), but at least with the parameters I got, I ended up with only with those unhandy(? - at least to me) thresholds.

Any feedback thats helps to get better is appreciated!

+2  A: 

I'm not sure what quantcut is but I would do the following

qdum <- function(v, q) {
 library(Hmisc)
 quantilenum <- cut2(v, g=q)
 levels(quantilenum) <- 1:q
 cbind(v, quantilenum)
}
Sameer
nice answer. Basically quantcut does exactly the same as quantcut. The difference making help was to replace levels by 1:q. I did not know this was possible. Thx Sameer!
ran2
+2  A: 

With base R, use quantiles to figure out the splits and then cut to convert the numeric variable to discrete:

qcut <- function(x, n) {
  cut(x, quantile(x, seq(0, 1, length = n + 1)), labels = seq_len(n),
    include.lowest = TRUE)
}

or if you just want the number:

qcut2 <- function(x, n) {
  findInterval(x, quantile(x, seq(0, 1, length = n + 1)), all.inside = T)
}
hadley
Looks like Hadley is trying to improve on his keystrokes per accepted answer ratio...
ran2