2016-11-28 2 views
0

Предположат, у вас есть неопределенный факс списков в качестве возможных аргументов для функции, например, следующие 3 может быть выбрано (этот пример как можно более простой, поэтому векторы сохраняются в списках):mapply несколько неопределенных аргументов

a <- list(c(1,2,3,4,5)) 
b <- list(c(3,6,7,2,1)) 
c <- list(c(3,9,8)) 

Если я хочу, чтобы вычислить пересечение всех трех списков, это может быть сделано следующим образом:

Map(intersect,c,Map(intersect,a,b)) 
# or equivalent: 
mapply(intersect,c,mapply(intersect,a,b,SIMPLIFY=F)) 
# [1] 3 

Но как я могу изменить номер факса аргументов неопределенным? Я читал около ..., но я не могу заставить его работать. Первая идея состояла в том, чтобы написать функцию, которая может иметь несколько аргументов списка, определенных ...:

intersectio <- function(...){ 
    Map(function(...){ 
    intersect(...) 
    }) 
} 

Q: Но это не работает, конечно, потому что пересекаются должны применяться рекурсивно. Есть ли способ достичь этого в R?

Q2: Ниже приведен пример с вложенной структурой списка. Как это можно сделать в этом случае, т. Е. Пересекать каждый подсписчик родительского списка с ассоциированным подсписком (тот же индекс) других родительских списков?

a <- list(list(c(1,2,3,4,5)),list(c(3,6,7,2,1)),list(c(3,9,8))) 
b <- list(list(c(1,2)),list(c(3,6,9,11,12)),list(c(3))) 
c <- list(list(c(1,9)),list(c(65,23,12)),list(c(14,15))) 
+2

'помощь ("Reduce")' – Roland

+0

intersectio <- функция (...) {Reduce (пересекаются, ...)} не работает. Более того, мои аргументы - фактически вложенные списки, а не простые векторы в списках, как указано выше. Так что это не так просто, как просто применить Reduce ... – user3032689

+2

Может быть, 'Reduce (function (x, y) Map (intersect, x, y), list (a, b, c))'? Вам необходимо предоставить репрезентативный воспроизводимый пример. – Roland

ответ

2

Как предложено @Roland, вы можете использовать Reduce для решения проблемы. В случае плоских списков (как в первой версии этого вопроса), вы можете использовать следующее:

Reduce(intersect, c(a, b, c)) 

В случае вложенных списков (как в обновленном вопросе), вы можете просто обернуть что внутри mapply вызова:

mapply(function(...) Reduce(intersect, c(...)), a, b, c) 

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

list_intersect <- function(...){ 
    mapply(function(...) Reduce(intersect, c(...)), ...) 
} 
list_intersect(a, b, c) 
+0

очень хорошо. Еще одно: здесь мы делаем это для a, b и c. Как бы выглядело это решение, если бы мы хотели его обобщить для неопределенного количества аргументов? Я не могу просто заменить a, b и c на '...' – user3032689

Смежные вопросы