Nishant Yadav
Nishant Yadav

Reputation: 1

Decreasing order of varaibles (columns) based on ranking in R

I have one data frame which has some non negative values (kind of rank) against 3 variables a,b and c

x <- data.frame(cbind(ID=c(1,2,3,4,5),a=c(14,20,0,14,0),b=c(20,0,20,12,0),c=c(12,12,0,0,20)))

+----------------+
|ID  | a | b | c |
+----------------+
|1   |14 |20 |12 |
|2   |20 |0  |12 |
|3   |0  |20 |0  |
|4   |14 |12 |0  |
|5   |0  |0  |20 |
+----------------+

I would like to compute a new variable "priority" which gives the priority in which the variables should be selected

+------------------------+
|ID  |a |b  |c  |priority|
+------------------------+
|1   |14|20 |12 |b>a>c   |
|2   |20|0  |12 |a>c     |
|3   |0 |20 |0  |b       |
|4   |14|12 |0  |a>b     |
|5   |0 |0  |20 |c       |
+------------------------+

Any help around how to create this kind of output in R is deeply appreciated.

Upvotes: 0

Views: 81

Answers (3)

DatamineR
DatamineR

Reputation: 9618

This way?

apply(x[-1], 1, function(x) paste(names(x)[x!=0][order(x[x!=0], 
    decreasing = T)], collapse = ">"))
[1] "b>a>c" "a>c"   "b"     "a>b"   "c"  

Upvotes: 0

randomSampling
randomSampling

Reputation: 136

colLabels=c("a","b","c")
sorting=function(x){
      sortedInd = (sort.int(x, index.return = TRUE, decreasing = TRUE))$ix
      sortedLabels = colLabels[sortedInd]
      paste(sortedLabels, collapse = ">")
}

x$priority = apply(x[,-1],1,sorting)

sortedInd returns the indices of each sorted row which is then fed to colLabels to get the corresponding labels. The labels are then combined using collapse as ">" in paste

Upvotes: 0

David Arenburg
David Arenburg

Reputation: 92282

Here's an attempt working with a long format and then joining back to the original data set

library(data.table) 
indx <- melt(setDT(x), 1L)[value > 0, 
             paste(variable[order(-value)], collapse = ">"), 
             by = ID]
x[indx, priority := i.V1, on = "ID"]
x
#    ID  a  b  c priority
# 1:  1 14 20 12    b>a>c
# 2:  2 20  0 12      a>c
# 3:  3  0 20  0        b
# 4:  4 14 12  0      a>b
# 5:  5  0  0 20        c

This basically "melts" the data by ID, filters by values greater than zero, orders/pastes column names by the values by IDs

Upvotes: 2

Related Questions