Применять поверх имен списков, а не элементов списка. E.g.:
somelist <- list('USA'=rnorm(10), 'Europe'=rnorm(10), 'Switzerland'=rnorm(10))
anotherlist <- list('USA'=5, 'Europe'=10, 'Switzerland'=4)
lapply(names(somelist), function(i) somelist[[i]] / anotherlist[[i]])
РЕДАКТИРОВАТЬ:
Вы также спрашиваете, существует ли способ «за исключением цикла» сделать это «эффективно». Вы должны отметить, что заявка не обязательно будет более эффективной. Эффективность, вероятно, будет зависеть от того, насколько быстро ваша внутренняя функция. Если вы хотите работать с каждым элементом списка, вам понадобится цикл, независимо от того, скрыт он в вызове apply () или нет. Проверьте этот вопрос: Является ли семейство R больше, чем синтаксический сахар?
Пример, который я привел выше, может быть переписан как цикл for, и вы можете сделать несколько наивных тестов:
fun1 <- function(){
lapply(names(somelist), function(i) somelist[[i]] / anotherlist[[i]])
}
fun2 <- function(){
for (i in names(somelist)){
somelist[[i]] <- somelist[[i]] / anotherlist[[i]]
}
return(somelist)
}
library(rbenchmark)
benchmark(fun1(), fun2(),
columns=c("test", "replications",
"elapsed", "relative"),
order="relative", replications=10000)
Результат теста на моей машине был таким:
test replications elapsed relative
1 fun1() 10000 0.145 1.000000
2 fun2() 10000 0.148 1.020690
Хотя это не настоящее рабочее приложение и функции не являются реалистичными задачами, вы можете видеть, что разница во времени вычислений весьма незначительна.