Reputation: 35
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
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