В качестве ориентира я предпочитаю применять функции на элементах списка, используя lapply или * ply (от plyr), а не явно итерации через них. Однако это хорошо работает, когда мне приходится обрабатывать один список за раз. Когда функция принимает несколько аргументов, я обычно делаю цикл.
Мне было интересно, возможно ли иметь более чистую конструкцию, все еще функциональную по своей природе. Одним из возможных подходов может быть определение функции, аналогичной Python, zip (x, y), которая берет входные списки и возвращает список, i-ый элемент которого является списком (x, y), а затем применяет функцию к этот список. Но мой вопрос заключается в том, использую ли я самый чистый подход или нет. Меня не беспокоит оптимизация производительности, а скорее ясность/элегантность.
Ниже приведен наивный пример.
A <- as.list(0:9)
B <- as.list(0:9)
f <- function(x, y) x^2+y
OUT <- list()
for (n in 1:10) OUT[[n]] <- f(A[[n]], B[[n]])
OUT
[[1]]
[1] 0
[[2]]
[1] 2
...
И вот пример с zipped (который может быть расширен до произвольных аргументов):
zip <- function(x, y){
stopifnot(length(x)==length(y))
z <- list()
for (i in seq_along(x)){
z[[i]] <- list(x[[i]], y[[i]])
}
z
}
E <- zip(A, B)
lapply(E, function(x) f(x[[1]], x[[2]]))
[[1]]
[1] 0
[[2]]
[1] 2
...