1

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?

Community
  • 1
  • 1
Bonono
  • 827
  • 1
  • 9
  • 18

1 Answers1

4

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]
akrun
  • 874,273
  • 37
  • 540
  • 662
  • I apologize, it seems I mistook OP's aim – bouncyball Oct 07 '16 at 15:56
  • @bouncyball It's okay, I was also misleaded by the post – akrun Oct 07 '16 at 15:57
  • This works to a certain extent. The list they create don't have the names of what is in column `ID.list$Id2`. Is this possible? – Bonono Oct 08 '16 at 14:05
  • 1
    @Bonono You can set the names as `setNames(lapply(....,), as.character(ID.list[[2]]))` – akrun Oct 08 '16 at 14:07
  • Please see my edit - I realised that in the real data that `ID.list` is slightly different. – Bonono Oct 09 '16 at 14:39
  • @Bonono I guess the `setNames(lapply(...), unique(t(apply(ID.list, 1, sort)))[,2])` should work, right? after changing the 'ID.list' to `ID.list2 <- as.data.frame(unique(t(apply(ID.list, 1, sort))), stringsAsFactors=FALSE)` – akrun Oct 09 '16 at 14:42