Invert a list / map

Often we use lists to map keywords onto values, for example

foo <- list(a=c("quark", "fark"), 
            b=c("quark", "foo", "bark"), 
            c=c("fark", "bark"))

To invert this list (such that “fark”, “bark” etc. become keywords, and “a”, “b” and “c” the values), do

foo.rev <- split(rep(names(foo), lengths(foo)), unlist(foo))

split splits a vector or data frame along a factor. In this case, we expand the names of foo using rep such that we get two vectors, as can be seen with the following command:

cbind(rep(names(foo), lengths(foo)), unlist(foo))

with the result

   [,1] [,2]   
a1 "a"  "quark"
a2 "a"  "fark" 
b1 "b"  "quark"
b2 "b"  "foo"  
b3 "b"  "bar"  
c1 "c"  "fark" 
c2 "c"  "bar"

When we apply split() to the first vector with the second to guide the split, we will get

[1] "b" "c"

[1] "a" "c"

[1] "b"

[1] "a" "b"