rlistcompare

How to compare two lists in R


I have two lists that I want to compare. I want to see if the values of each element of the list are equal or not.

> m1
[[1]]
integer(0)

[[2]]
[1] 3 4

[[3]]
integer(0)

[[4]]
[1] 1

[[5]]
[1] 2 3 4

> m3
[[1]]
[1] 3

[[2]]
[1] 1 4

[[3]]
[1] 2

[[4]]
[1] 3

[[5]]
[1] 1 4

And I expect a result like this:

> Result
[[1]]
[1]
FALSE

[[2]]
[1] 
FALSE TRUE

[[3]]
[1]
FALSE

[[4]]
[1]
FALSE

[[5]]
[1] 
FALSE FALSE TRUE

If I try to apply m1[1] == m3[1] or similar, I get messages as

Error in m1 == m3 : comparison of these types is not implemented.

I don't manage to do that simple thing! Thanks for your help in advance.

Data

m1 <- list(integer(0), 3:4, integer(0), 1, 2:4)
m3 <- list(3, c(1, 4), 2, 3, c(1, 4))

Solution

  • You can use Map(or mapply) with %in%.

    Map(`%in%`, m1, m3)
    
    # [[1]]
    # logical(0)
    # 
    # [[2]]
    # [1] FALSE  TRUE
    # 
    # [[3]]
    # logical(0)
    # 
    # [[4]]
    # [1] FALSE
    # 
    # [[5]]
    # [1] FALSE FALSE  TRUE
    

    However, m1 contains integer(0), which makes %in% return logical(0) instead of FALSE. So you need to convert logical(0) to FALSE afterward.

    res <- Map(`%in%`, m1, m3)
    res[lengths(res) == 0] <- FALSE
    res
    
    # [[1]]
    # [1] FALSE
    # 
    # [[2]]
    # [1] FALSE  TRUE
    # 
    # [[3]]
    # [1] FALSE
    # 
    # [[4]]
    # [1] FALSE
    # 
    # [[5]]
    # [1] FALSE FALSE  TRUE
    

    Update

    Another one-liner solution:

    Map(\(x, y) x[seq_len(max(1, length(x)))] %in% y, m1, m3)
    

    Note: integer(0)[1] is NA and NA %in% y returns FALSE.