Bonono Bonono - 2 months ago 7
R Question

Merge vectors in list based on matching names of elements

I have a list that I want to merge:

path_list <- list(a = c("path1","path2","path3"), b= c("path4","path5"), c= c("path6","path7"), d = c("path8","path9","path10"))

path_list
$a
[1] "path1" "path2" "path3"

$b
[1] "path4" "path5"

$c
[1] "path6" "path7"

$d
[1] "path8" "path9" "path10"


I want to merge the elements in them based on the
data.frame
below:

ID.list <- data.frame(Id1 = c("a","b", "c","d"), Id2 = c("c","d","a","b"))

Id1 Id2
a c
b d


So that
a-c
merge together as do
b-d
, giving the name of
ID.list$ID2
.

result
$c
[1] "path1" "path2" "path3" "path6" "path7"

$d
[1] "path4" "path5" "path8" "path9" "path10"


Is this possible? I looked at this but my real data has 40
Ids
so couldn't figure out how to do it.

EDIT:

Note that the merge between
a-c
will be the same as
c-a
(same goes for
b-d
)
. How would I go about deleting the duplicates even though they have different names?

Answer

We can loop through the sequence of rows of 'ID.list', subset the elements of 'ID.list', use that as index to get the 'path_list' elements and unlist it.

lapply(seq_len(nrow(ID.list)), function(i)  
     unlist(path_list[as.character(unlist(ID.list[i,]))], use.names=FALSE))

Or another option is split by row and then subset it

lapply(split(as.matrix(ID.list), row(ID.list)), function(x) 
                              unlist(path_list[x], use.names = FALSE))

Update

If there are elements in 'ID.list' in reverse, perhaps this should work

ID.list2 <- as.data.frame(unique(t(apply(ID.list, 1, sort))), 
              stringsAsFactors=FALSE) 
lst <- lapply(seq_len(nrow(ID.list2)), function(i)  
    unlist(path_list[as.character(unlist(ID.list2[i,]))], use.names=FALSE))
names(lst) <- ID.list2[,2]