Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to turn a list inside out?

Tags:

r

base

purrr

I've got a following list:

> list(c(3, 4, 5, 8), c(2, 6, 9, 10), c(1, 7))
[[1]]
[1] 3 4 5 8

[[2]]
[1]  2  6  9 10

[[3]]
[1] 1 7

So we can say that 3 belongs to group 1, 6 belongs to group 2, 7 belongs to group 3 and so on. I need a reverse mapping, i.e. to every number I want to have a group id that it belongs to (see expected output):

> list(3, 2, 1, 1, 1, 2, 3, 1, 2, 2)
[[1]]
[1] 3

[[2]]
[1] 2

[[3]]
[1] 1

[[4]]
[1] 1

[[5]]
[1] 1

[[6]]
[1] 2

[[7]]
[1] 3

[[8]]
[1] 1

[[9]]
[1] 2

[[10]]
[1] 2

I thought purrr::transpose should do the job but it doesn't exactly do what I intend, is it? How can it be done?

PS. Ultimately, I need just a vector of a form: 3 2 1 1 1 2 3 1 2 2, but having above I think unlist() is enough to convert.

like image 349
jakes Avatar asked Jan 13 '19 06:01

jakes


2 Answers

Here is a base solution ...

list <- list(c(3, 4, 5, 8), c(2, 6, 9, 10), c(1, 7))

rep(1:length(list), sapply(list, length))[order(unlist(list))]
like image 74
Khaynes Avatar answered Nov 15 '22 23:11

Khaynes


Can I suggest an old-fashioned loop:

# your list
x <- list(c(3, 4, 5, 8), c(2, 6, 9, 10), c(1, 7))
# the data in the list as vector
num <- unlist( x )
# the variable that will be the position vector
pos <- NULL

# loop through the possible position, see which number it contains
# find which "group it belongs to, and add that finding to the position vector
for( i in 1:length( num ) )
    for( j in  1:length( x ) )
        if( i %in% x[[j]] ) pos <- c( pos, j )

pos
[1] 3 2 1 1 1 2 3 1 2 2
like image 2
vaettchen Avatar answered Nov 15 '22 22:11

vaettchen