How to perform a paired operation of type `% in%` and set operations for a list of vectors

This question is motivated. How can I quickly see if any elements from several vectors in R are equal? but not identical / duplicated.

As a small example, suppose we have a list of 4 vectors:

set.seed(0)
lst <- list(vec1 = sample(1:10, 2, TRUE), vec2 = sample(1:10, 3, TRUE),
            vec3 = sample(1:10, 4, TRUE), vec4 = sample(1:10, 5, TRUE))

How can we carry out paired binary operations, such as %in%, and set operations: intersect, union, setdiff?

Suppose we want pairwise "%in%", how can we further perform any()/ all()/ which()in each pair?

Note. I do not want to use combn().

+4
source share
1 answer

outer(x, y, FUN). x y "" , , /; , "" / " ".

, "%in%",

z <- outer(lst, lst, FUN = Vectorize("%in%", SIMPLIFY = FALSE, USE.NAMES = FALSE))
#     vec1      vec2      vec3      vec4     
#vec1 Logical,2 Logical,2 Logical,2 Logical,2
#vec2 Logical,3 Logical,3 Logical,3 Logical,3
#vec3 Logical,4 Logical,4 Logical,4 Logical,4
#vec4 Logical,5 Logical,5 Logical,5 Logical,5

"%in%" , Vectorized("%in%"). SIMPLIFY = FALSE, FUN -1 (x[[i]], y[[j]]). , outer :

y[[4]] | FUN(x[[1]], y[[4]])  FUN(x[[2]], y[[4]])  FUN(x[[1]], y[[4]])  FUN(x[[2]], y[[4]])
y[[3]] | FUN(x[[1]], y[[3]])  FUN(x[[2]], y[[3]])  FUN(x[[1]], y[[3]])  FUN(x[[2]], y[[4]])
y[[2]] | FUN(x[[1]], y[[2]])  FUN(x[[2]], y[[2]])  FUN(x[[1]], y[[2]])  FUN(x[[2]], y[[4]])
y[[1]] | FUN(x[[1]], y[[1]])  FUN(x[[2]], y[[1]])  FUN(x[[1]], y[[1]])  FUN(x[[2]], y[[4]])
         -------------------  -------------------  -------------------  -------------------
         x[[1]]               x[[2]]               x[[3]]               x[[4]]

, length(FUN(x, y)) == length(x) * length(y). SIMPLIFY = FALSE, .

z - " ", class(z) "", typeof(z) "". ? .


z, lapply. .

1: any()

any(a %in% b) , any(b %in% a), .. , z:

lz <- z[lower.tri(z)]

lapply , . (i, j) :

ind <- which(lower.tri(z), arr.ind = TRUE)
NAME <- paste(ind[,1], ind[,2], sep = ":")
any_lz <- setNames(lapply(lz, any), NAME)

#List of 6
# $ 2:1: logi FALSE
# $ 3:1: logi TRUE
# $ 4:1: logi TRUE
# $ 3:2: logi TRUE
# $ 4:2: logi FALSE
# $ 4:3: logi TRUE

, intersect, union setequal, , .

2: which()

which(a %in% b) , .

NAME <- paste(1:nrow(z), rep(1:nrow(z), each = ncol(z)), sep = ":")
which_z <- setNames(lapply(z, which), NAME)

# List of 16
#  $ 1:1: int [1:2] 1 2
#  $ 2:1: int(0) 
#  $ 3:1: int [1:2] 1 2
#  $ 4:1: int 3
#  $ 1:2: int(0) 
#  $ 2:2: int [1:3] 1 2 3
#  ...

, setdiff, .


outer(), R- z . , "%in%" :

op <- "'%in%'"    ## operator

lst_name <- names(lst)
op_call <- paste0(op, "(", lst_name, ", ", rep(lst_name, each = length(lst)), ")")
# [1] "'%in%'(vec1, vec1)" "'%in%'(vec2, vec1)" "'%in%'(vec3, vec1)"
# [4] "'%in%'(vec4, vec1)" "'%in%'(vec1, vec2)" "'%in%'(vec2, vec2)"
# ...

lst. :

NAME <- paste(1:length(lst), rep(1:length(lst), each = length(lst)), sep = ":")
z <- setNames(lapply(parse(text = op_call), eval, lst), NAME)

# List of 16
#  $ 1:1: logi [1:2] TRUE TRUE
#  $ 2:1: logi [1:3] FALSE FALSE FALSE
#  $ 3:1: logi [1:4] TRUE TRUE FALSE FALSE
#  $ 4:1: logi [1:5] FALSE FALSE TRUE FALSE FALSE
#  $ 1:2: logi [1:2] FALSE FALSE
#  ...
+4

Source: https://habr.com/ru/post/1651944/


All Articles