How can I operate on all combinations of 2 list elements?

64 Views Asked by At

I have to compare all the elements in the list with each other, dog vs cat, dog vs mouse, cat vs mouse.

animals <- list(
  dog = data.frame(
    col_1 = sample(c(100:200), size = 10, replace = TRUE),
    col_2 = sample(c(100:200), size = 10, replace = TRUE),
    col_3 = sample(c(100:200), size = 10, replace = TRUE),
    col_4 = sample(c(100:200), size = 10, replace = TRUE)
  ),
  cat = data.frame(
    col_1 = sample(c(100:200), size = 10, replace = TRUE),
    col_2 = sample(c(100:200), size = 10, replace = TRUE),
    col_3 = sample(c(100:200), size = 10, replace = TRUE),
    col_4 = sample(c(100:200), size = 10, replace = TRUE)
  ),
  mouse = data.frame(
    col_1 = sample(c(100:200), size = 10, replace = TRUE),
    col_2 = sample(c(100:200), size = 10, replace = TRUE),
    col_3 = sample(c(100:200), size = 10, replace = TRUE),
    col_4 = sample(c(100:200), size = 10, replace = TRUE)
   )
)

I want to compare every combination of two dataframes from the above. The type of comparison isn't important - it's sufficient to say this can be done via a generic_function() like so:

generic_function(animals$dog[, c("col_1", "col_2")],
                 animals$cat[, c("col_1", "col_2")])

Since there is a lot of data to compare, I would like to use lapply function, but I don't know how to create the intersections between the various levels of the list. Can you help me?

3

There are 3 best solutions below

0
wurli On BEST ANSWER

You can generate combinations with combn() and then iterate over combinations using lapply():

animals <- list(
  dog = data.frame(
    col_1 = sample(c(100:200), size = 10, replace = TRUE),
    col_2 = sample(c(100:200), size = 10, replace = TRUE),
    col_3 = sample(c(100:200), size = 10, replace = TRUE),
    col_4 = sample(c(100:200), size = 10, replace = TRUE)
  ),
  cat = data.frame(
    col_1 = sample(c(100:200), size = 10, replace = TRUE),
    col_2 = sample(c(100:200), size = 10, replace = TRUE),
    col_3 = sample(c(100:200), size = 10, replace = TRUE),
    col_4 = sample(c(100:200), size = 10, replace = TRUE)
  ),
  mouse = data.frame(
    col_1 = sample(c(100:200), size = 10, replace = TRUE),
    col_2 = sample(c(100:200), size = 10, replace = TRUE),
    col_3 = sample(c(100:200), size = 10, replace = TRUE),
    col_4 = sample(c(100:200), size = 10, replace = TRUE)
  )
)


combinations <- asplit(combn(names(animals), 2), 2)

print(combinations)
#> [[1]]
#> [1] "dog" "cat"
#> 
#> [[2]]
#> [1] "dog"   "mouse"
#> 
#> [[3]]
#> [1] "cat"   "mouse"

lapply(combinations, function(x) {
  generic_function(
    animals[[x[1]]][, c("col_1", "col_2")],
    animals[[x[2]]][, c("col_1", "col_2")]
  )
})

Created on 2024-03-14 with reprex v2.1.0

0
s_baldur On
n <- length(animals)
cols <- c("col_1", "col_2")
lapply(1:(n-1), \(i) lapply((i+1):n, \(j) generic_function(animals[[i]][cols], animals[[j]][cols]))) |> 
  unlist(recursive = FALSE)
0
ThomasIsCoding On

You can use combn like below

combn(
   lapply(animals, `[`, c("col_1", "col_2")),
   2,
   FUN = \(x) do.call(generic_function, x),
   simplify = FALSE
)