почтовые списки в R - PullRequest
       47

почтовые списки в R

16 голосов
/ 27 мая 2011

В качестве руководства я предпочитаю применять функции к элементам списка, используя lapply или * ply (из plyr), а не явно итерируя их. Тем не менее, это хорошо работает, когда мне нужно обрабатывать один список за раз. Когда функция принимает несколько аргументов, я обычно делаю цикл.

Мне было интересно, возможно ли иметь более чистую конструкцию, все еще функциональную по своей природе. Одним из возможных подходов может быть определение функции, аналогичной Python, zip (x, y), которая принимает входные списки и возвращает список, i-тым элементом которого является list (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

        ...

А вот сжатый пример (который может быть расширен до произвольных аргументов):

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

 ...

Ответы [ 3 ]

27 голосов
/ 27 мая 2011

Я думаю, что вы ищете mapply:

   ‘mapply’ is a multivariate version of ‘sapply’.  ‘mapply’ applies
     ‘FUN’ to the first elements of each ...  argument, the second
     elements, the third elements, and so on.  Arguments are recycled
     if necessary.
1 голос
/ 23 января 2019

Я встретил подобную проблему сегодня.И после изучения использования func mapply, я знаю, как решить это сейчас.

mapply это так круто!

Вот несколько примеров заметки:

en = c("cattle", "chicken", "pig")
zh = c("牛",      "鸡",      "猪")

dict <- new.env(hash = TRUE)
Add <- function(key, val) dict[[key]] <- val

mapply(Add, en, zh)
##  cattle chicken     pig 
##    "牛"    "鸡"    "猪" 

END.

1 голос
/ 27 мая 2011

Я думаю, что вы могли бы сделать это с помощью того, что я называю «неявным циклом» (это имя не попадает в него полностью, но как угодно), учитывая, что вы можете зацикливать векторы в *apply:

OUT <- lapply(1:10, function(x) (A[[x]]^2 + B[[x]]))

или

OUT <- lapply(1:10, function(x) f(A[[x]], B[[x]]))

Обратите внимание, что тогда вы также можете использовать vapply (или 'sapply`) для управления выводом (т. Е. Если вам не нужен список).

(кстати, я не получаю то, что вы хотите с помощью функции zip, поэтому извините, если я пропустил вашу мысль.)

...