сопоставление пар элементов в списках в R

#r #mapply

Вопрос:

Если у меня есть симметричный двоичный оператор, который я хочу применить к парам элементов из списка, есть ли простой способ сделать это в R? Я пытался:

 A <- list(1,2,3)
mapply(function(x,y) x y, A,A)
 

но это дает только x[n] y[n] для всех n=1..N , но я хочу x[n] y[m] , чтобы все m=1..n, n=1..N возвращалось в виде списка. outer(..) делает это, для m=1..N, n=1..N чего требуются избыточные вычисления, поэтому я хочу это исключить.

Обратите внимание, что мне не нужно решение этого простого примера. Мне нужно общее решение, которое работает и для нечислового ввода. То, что я пытаюсь сделать, это как:

 mapply(function(set_1, set_2) setequal(intersect(set_1, set_2),  set_3), list_of_sets, list_of_sets)
 

В обоих случаях сложение и пересечение симметричны. В первом примере я ожидаю list(3,4,5) от list(1 2,1 3,2 3) . Для второго случая мой ввод list_of_sets -это:

 > list_of_sets
[[1]]
numeric(0)

[[2]]
[1] 1

[[3]]
[1] 2

[[4]]
[1] 1 2

[[5]]
[1] 3

[[6]]
[1] 1 3

[[7]]
[1] 2 3

[[8]]
[1] 1 2 3
 

и set_3 быть c(1,2) в качестве простого примера.

Комментарии:

1. Что-то вроде mapply(` `, list(1,2,3), list(c(1,2,3)) ) «может быть»?

2. Хорошо, просто проголосовал за повторное рассмотрение этого вопроса

3. @monotonic Я показал вариант с combn » Работает ли это для вас?»

4. чего вы ожидаете в качестве результата list_of_sets ?

Ответ №1:

Вы можете использовать outer

 values <- c(1, 2, 3)
outer(values, values, ` `)

#     [,1] [,2] [,3]
#[1,]    2    3    4
#[2,]    3    4    5
#[3,]    4    5    6
 

outer также работает для нечислового ввода. Если функция, которую вы хотите применить, не векторизована, вы можете ее использовать Vectorize . Поскольку ОП не привел примера, я создал свой собственный.

 list_of_sets_1 <- list(c('a', 'b', 'c'), c('a'))
list_of_sets_2 <- list(c('a', 'c'), c('a', 'b'))

fun <- function(x, y) intersect(x, y)
result <- outer(list_of_sets_1, list_of_sets_2, Vectorize(fun))
result
 

Комментарии:

1. Привет, хотя это не относится к более сложному вводу. Я просто использую этот случай в качестве примера.

2. Я отредактировал, чтобы включить пример.

3. Я немного отредактировал вопрос, чтобы сделать его более конкретным для симметричных двоичных операторов.

Ответ №2:

Нам нужно combn выполнять попарные вычисления без избыточности

 combn(A, 2, FUN = function(x) x[[1]]   x[[2]], simplify = FALSE)
 

-выход

 [[1]]
[1] 3

[[2]]
[1] 4

[[3]]
[1] 5
 

Это также будет работать с нечисловыми элементами

 list_of_sets <- list(c('a', 'b', 'c'), "a", c("a", "c"))
combn(list_of_sets, 2, FUN = function(x) Reduce(intersect, x), simplify = FALSE)
 

-выход

 [[1]]
[1] "a"

[[2]]
[1] "a" "c"

[[3]]
[1] "a"
 

Мы также можем сделать

 combn(list_of_sets, 2, FUN = function(x) 
   setequal(intersect(x[[1]], x[[2]]), set_3), simplify = FALSE)
 

Комментарии:

1. Привет, я немного обновил вопрос. Можно ли это сделать без «Сокращения»?

2. @монотонный ты имел в виду combn(list_of_sets, 2, FUN = function(x) intersect(x[[1]], x[[2]]), simplify = FALSE)

3. @монотонно можно ли показать ожидаемые выходные list_of_sets данные вместе с входными данными, чтобы было проще проверить

4. Конечно. Пример: > set_1 [[1]] numeric(0) [[2]] [1] 1 [[3]] [1] 2 [[4]] [1] 1 2 [[5]] [1] 3 [[6]] [1] 1 3 [[7]] [1] 2 3 [[8]] [1] 1 2 3

5. @monotonic пожалуйста, обновите свой пост небольшим подходящим примером и ожидаемым результатом. Из комментариев трудно прочитать