user3259686
user3259686

Reputation: 11

in R: How do I rank each individual data frame in a list of data frames?

I've simplified my problem conceptually as follows. I have a list (mylist) comprised of two data frames. I know how to reorder them both (say, on the 4th and 1st variable) using lapply:

mylist<-lapply(mylist, function(x) x[order(x[,4],x[,1]),])

Now I am trying to use lapply() and rank() to add a 5th column to each dataframe in the list, and populate the column with the rank (the rank within that dataframe, on the 4th variable say).

Ive tried dozens of permutations of this

mylist[,5]<-lapply(mylist, function(x) rank(x[,4], ties.method="first")) 

nothing works right. Help! Thanks

> mylist
[[1]]
a b c d
1 1 4 7 A
2 2 5 8 A
3 3 6 9 B

[[2]]
a b c d
1 9 6 3 A
2 8 5 2 A
3 7 4 1 B

Upvotes: 1

Views: 527

Answers (3)

dickoa
dickoa

Reputation: 18437

Using the data provided by @JakeBurkhead, you can simply use transform

set.seed(123)
mylist <- list(data.frame(a = rnorm(5), b = rpois(5, 3)),
               data.frame(a = rnorm(5), b = rpois(5, 3)) )
lapply(mylist, transform, c = rank(b, ties.method = "first"))
## [[1]]
##           a b c
## 1 -0.560476 6 5
## 2 -0.230177 3 2
## 3  1.558708 4 4
## 4  0.070508 3 3
## 5  0.129288 1 1

## [[2]]
##          a b c
## 1  1.28055 4 5
## 2 -1.72727 3 3
## 3  1.69018 3 4
## 4  0.50381 2 2
## 5  2.52834 1 1

Upvotes: 0

Jake Burkhead
Jake Burkhead

Reputation: 6535

Your lapply returns the output of rank which is a vector. You need to append a column to each data.frame then return the data.frame

mylist <- list(data.frame(a = rnorm(5), b = rpois(5, 3)), data.frame(a = rnorm(5), b = rpois(5, 3)) )
mylist
## [[1]]
##             a b
## 1 -1.31730854 4
## 2  0.04395243 1
## 3  0.15370905 0
## 4 -0.77556501 4
## 5  1.12879380 4
## 
## [[2]]
##             a b
## 1 -0.96314478 3
## 2 -0.54824004 6
## 3  0.34943917 1
## 4 -0.07077913 0
## 5  1.10519356 3

lapply(mylist, function(x) { x$c <- rank(x$b); x })
## [[1]]
##             a b c
## 1 -1.31730854 4 4
## 2  0.04395243 1 2
## 3  0.15370905 0 1
## 4 -0.77556501 4 4
## 5  1.12879380 4 4
## 
## [[2]]
##             a b   c
## 1 -0.96314478 3 3.5
## 2 -0.54824004 6 5.0
## 3  0.34943917 1 2.0
## 4 -0.07077913 0 1.0
## 5  1.10519356 3 3.5

Upvotes: 0

IRTFM
IRTFM

Reputation: 263331

Well it couldn't be:

  mylist[,5]<-lapply(mylist, function(x) rank(x[,4], ties.method="first")) 

... because mylist[,5] doesn't make any sense. mylist you said was a two element list so it really didn't even have columns. So you need to loop over the elements and add the column to them individually:

 mylist <-lapply(mylist, function(x) { rl <- rank( x[,4], ties.method="first")
                                      x <- cbind( x, rl=rl) 
                                      x [ order(x['rl']) , ] } )

Upvotes: 2

Related Questions