Manuel Silva
Manuel Silva

Reputation: 35

R Order elements of list

I want to order 2 lists in R and intersect both on the 2 elements with most length. example:

Membership1
[[1]]
 [1]   3   4   6   7   8 

[[2]]
 [1]   5  13  23  

[[3]]
 [1]   1   2  12  14  15  16  18  21  25  28  

Membership2
[[1]]
 [1]   8  13  20  21  23 

[[2]]
 [1]   3   6   7   

[[3]]
 [1]   1   2   4   5  10  15  17  19  24  25  29  

Here, the result would be:

[[3]]
     [1]   1   2  12  14  15  16  18  21  25  28  
 [[1]]
     [1]   3   4   6   7   8 
 [[2]]
     [1]   5  13  23  

and

 [[3]]
     [1]   1   2   4   5  10  15  17  19  24  25  29  
 [[1]]
     [1]   8  13  20  21  23 
 [[2]]
     [1]   3   6   7  

And then 1, 2, 15, 25 and 8 (intersect of both [[3]])

The intersect function is pretty straighforward, but I don´t understand how to order those lists the way I want.

Manuel

Upvotes: 1

Views: 6538

Answers (1)

gagolews
gagolews

Reputation: 13056

To order a list w.r.t. the lengths of its elements, nonincreasingly, call:

x <- list(1:5, 1:3, 1:7)
(x <- x[order(sapply(x, length), decreasing=TRUE)])
## [[1]]
## [1] 1 2 3 4 5 6 7
## 
## [[2]]
## [1] 1 2 3 4 5
## 
## [[3]]
## [1] 1 2 3

Thus, the whole task may be solved with e.g.:

Membership1 <- list(c(3, 4, 6, 7, 8), c(5, 13, 23), c(1, 2, 12, 14, 15, 16, 18, 21, 25, 28))
Membership2 <- list(c(8, 13, 20, 21, 23), c(3, 6, 7), c(1, 2, 4, 5, 10, 15, 17, 19, 24, 25, 29))
Membership1 <- Membership1[order(sapply(Membership1, length), decreasing=TRUE)]
Membership2 <- Membership2[order(sapply(Membership2, length), decreasing=TRUE)]
lapply(seq_along(Membership1), function(i) intersect(Membership1[[i]], Membership2[[i]]))
## [[1]]
## [1]  1  2 15 25
## 
## [[2]]
## [1] 8
## 
## [[3]]
## numeric(0)

Equivalently, as @flodel suggested, the last step may be performed as follows:

Map(intersect, Membership1, Membership2)

or even:

mapply(intersect, Membership1, Membership2, SIMPLIFY=FALSE)

Upvotes: 2

Related Questions