Shankar_m
Shankar_m

Reputation: 65

Rank function to rank multiple variables in R

I am trying to rank multiple numeric variables ( around 700+ variables) in the data and am not sure exactly how to do this as I am still pretty new to using R.

I do not want to overwrite the ranked values in the same variable and hence need to create a new rank variable for each of these numeric variables.

From reading the posts, I believe assign and transform function along with rank maybe able to solve this. I tried implementing as below ( sample data and code) and am struggling to get it to work.

The output dataset in addition to variables xcount, xvisit, ysales need to be populated With variables xcount_rank, xvisit_rank, ysales_rank containing the ranked values.

input <- read.table(header=F, text="101 2 5 6 
                102 3 4 7 
                103 9 12 15")
colnames(input) <- c("id","xcount","xvisit","ysales")

input1 <- input[,2:4] #need to rank the numeric variables besides id

for (i in 1:3) 
{
  transform(input1, 
            assign(paste(input1[,i],"rank",sep="_")) = 
              FUN = rank(-input1[,i], ties.method = "first"))
}






input[paste(names(input)[2:4], "rank", sep = "_")] <- 
     lapply(input[2:4], cut, breaks = 10)

The problem with this approach is that it's creating the rank values as (101, 230] , (230, 450] etc whereas I would like to see the values in the rank variable to be populated as 1, 2 etc up to 10 categories as per the splits I did. Is there any way to achieve this? input[5:7] <- lapply(input[5:7], rank, ties.method = "first")

The approach I tried from the solutions provided below is:

   input <- read.table(header=F, text="101 20 5 6 
                102 2 4 7 
                103 9 12 15
                104 100 8 7 
                105 450 12 65 
                109 25 28 145
                112 854 56 93")
   colnames(input) <- c("id","xcount","xvisit","ysales")

   input[paste(names(input)[2:4], "rank", sep = "_")] <- 
           lapply(input[2:4], cut, breaks = 3)

   Current output I get is:
   id xcount xvisit ysales xcount_rank xvisit_rank ysales_rank
    1 101     20      5      6  (1.15,286] (3.95,21.3] (5.86,52.3]
    2 102      2      4      7  (1.15,286] (3.95,21.3] (5.86,52.3]
    3 103      9     12     15  (1.15,286] (3.95,21.3] (5.86,52.3]
    4 104    100      8      7  (1.15,286] (3.95,21.3] (5.86,52.3]
    5 105    450     12     65   (286,570] (3.95,21.3] (52.3,98.7]
    6 109     25     28    145  (1.15,286] (21.3,38.7]  (98.7,145]
    7 112    854     56     93   (570,855] (38.7,56.1] (52.3,98.7]

    Desired output:
     id xcount xvisit ysales xcount_rank xvisit_rank ysales_rank
     1 101     20      5      6  1           1           1
     2 102      2      4      7  1           1           1
     3 103      9     12     15  1           1           1
     4 104    100      8      7  1           1           1
     5 105    450     12     65  2           1           2
     6 109     25     28    145  1           2           3

Would like to see the records in the group they would fall under if I try to rank the interval values.

Upvotes: 1

Views: 3275

Answers (1)

akrun
akrun

Reputation: 887991

Using dplyr

 library(dplyr)
  nm1 <- paste("rank", names(input)[2:4], sep="_")
  input[nm1] <-  mutate_each(input[2:4],funs(rank(., ties.method="first")))
  input
  #   id xcount xvisit ysales rank_xcount rank_xvisit rank_ysales
  #1 101      2      5      6           1           2           1
  #2 102      3      4      7           2           1           2
  #3 103      9     12     15           3           3           3

Update

Based on the new input and using cut

  input[nm1] <- mutate_each(input[2:4], funs(cut(., breaks=3, labels=FALSE)))
  input
  #   id xcount xvisit ysales rank_xcount rank_xvisit rank_ysales
  #1 101     20      5      6           1           1           1
  #2 102      2      4      7           1           1           1
  #3 103      9     12     15           1           1           1
  #4 104    100      8      7           1           1           1
  #5 105    450     12     65           2           1           2
  #6 109     25     28    145           1           2           3
  #7 112    854     56     93           3           3           2

Upvotes: 2

Related Questions