lapply для каждого элемента списка списков

Как я могу выполнить одну и ту же функцию (здесь: load.image) для каждого элемента списка списков?

Отправной точкой является этот список из двух списков:

list1 <- list(c("Group1", "Group2", "Group3"))
list2 <- list(c("GroupA", "GroupB", "GroupC"))
list.all <- c(list1,list2)

Я написал эту функцию, которая применяется последовательно итеративно:

    images.list.function <- lapply(
      designs.path.list, 
      FUN = function(secondlevel.list) 
        lapply(secondlevel.list, function(x) load.image(x))
    )
    # read all jpgs into a list
    images.list <- images.list.function
    images.list

Это работает правильно, но мне нужен формат, не зависящий от количества уровней, потому что в будущем может быть добавлен третий или четвертый уровень.

Какие-нибудь изящные мысли?


person Agile Bean    schedule 07.04.2017    source источник


Ответы (3)


Я нашел новое решение, которое даже проще, чем элегантное решение Р. Скифини, поэтому теперь отвечаю на свой вопрос :)

Семейство apply также предоставляет рекурсивную версию под названием rapply, и она отлично работает с вложенными списками, см. эти примеры.

Применяя это к проблеме, решение просто:

images.list <- rapply(designs.path.list, load.image)

Вот и все.

person Agile Bean    schedule 02.02.2019

Это полезно?

flatList = unlist(list.all)
[1] "Group1" "Group2" "Group3" "GroupA" "GroupB" "GroupC"

Используя unlist, вы получите вектор. Затем используйте lapply с функцией загрузки изображений.

Например, используя функцию paste, чтобы добавить "-image" к каждому имени:

d = lapply(flatList, function(x){paste(x, "-image", sep = "")})
> d
[[1]]
[1] "Group1-image"

[[2]]
[1] "Group2-image"

[[3]]
[1] "Group3-image"

[[4]]
[1] "GroupA-image"

[[5]]
[1] "GroupB-image"

[[6]]
[1] "GroupC-image"
person R. Schifini    schedule 29.07.2017
comment
@ R.Schifni, это действительно изящный трюк! спасибо и извините за задержку, пропустил уведомление. но я все еще могу использовать его в моем текущем коде. - person Agile Bean; 02.02.2019

Мне нравится ответ Р. Скифини. Но чтобы немного оживить его, у вас также есть доступ к do.call.

Просто сделайте повторный вызов столько уровней, сколько вам нужно:

do.call(c,do.call(c,list.all))...

это должно дать вам вектор всех элементов ...

person Jorge Lopez    schedule 02.02.2019
comment
Если показать, как это применимо к проблеме OP (используя их образцы данных и предоставив результат), это будет гораздо лучший ответ. - person Nick; 02.02.2019
comment
@ Хорхе Лопес, спасибо за вашу идею, но я хотел что-то, что не зависело бы от того, сколько уровней существует - person Agile Bean; 02.02.2019
comment
Я думаю, что Agile Bean прекрасно понял, что я имел в виду, Ник. Мой ответ должен быть адресован человеку, которому я пишу, независимо от того, какой ответ третьи лица сочтут правильным или нет. Но спасибо, что написал строчку, Ник. Видите, как мои ответы должны быть поняты только тому человеку, которому я пишу? - person Jorge Lopez; 03.02.2019