Возврат списка списков из цикла foreach в R - PullRequest
0 голосов
/ 06 декабря 2018

У меня есть функция, которая возвращает список из двух объектов (список l и число n).Я хочу зациклить эту функцию в цикле foreach.

create_lists <- function(){
l = sample(100, 5)
n = sample(100, 1)
return(list(l=l, n=n))}

Поскольку create_lists имеет список в качестве вывода, этот пост сказал мне использовать функцию объединения, которая выглядитвот так:

combine_custom <- function(list1, list2){
  ls = c(list1$l, list2$l)
  ns = c(list1$n, list2$n)
  return(list(l = ls, n = ns))
}

Так что теперь мой цикл foreach выглядит так:

m = foreach(i=1:5, .combine = combine_custom)%do%{
   create_lists()}

Мой желаемый результат будет:

m$l
[[1]]
[1] 100  25  86  21  28

[[2]]
[1] 78 37 79 41 61

[[3]]
[1] 73 22 78 94 13

[[4]]
[1] 15 28 76 78 52

[[5]]
[1] 32 93 92  2  1

m$n
[1] 52 56 3 79 82

Но что яget выглядит примерно так:

$l
 [1] 84 28 75 59 68 84 28 75 59 68

$n
[1] 31 91 18 98 39

Итак, у меня две проблемы: 1) Почему отбрасывается все, кроме двух списков l?2) Как я могу сделать m$l списком списков?

РЕДАКТИРОВАТЬ: Я попробовал другой подход, полученный из здесь , который не использует c:

combine_custom <- function(list1, list2){
      ls = list1$l[[length(list1$l)+1]] = list(list2$l)
      ns = c(list1$n, list2$n)
      return(list(l = ls, n = ns))
    }

Но это дало тот же результат, что и описанный выше, а именно:

$l
$l[[1]]
[1] 65 84 48 81 82


$n
[1] 88 79 92 36 71

Ответы [ 2 ]

0 голосов
/ 06 декабря 2018

Я нашел другой способ, который позволяет избежать проблемы, упомянутой выше, а именно, что combine должен сначала создать новый список, а затем добавлять только списки.Кроме того, реальная функция, которую я использую, на самом деле возвращает список списков, поэтому следующее оказалось полезным:

combine_custom <- function(list1, list2) {
     if (plotrix::listDepth(list1$l) > plotrix::listDepth(list2$l)) {
        ls  <- c(list1$l, list(list2$l))
    } else {
        ls <- c(list(list1$l), list(list2$l))
     }
     ns <- c(list1$n, list2$n)
     return(list(l = ls, n = ns))
}

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

0 голосов
/ 06 декабря 2018

Часть combine доставляет много хлопот, потому что на первой итерации необходимо составить список из двух списков, а на второй итерации - добавить один список в качестве элемента в список.списков.

Другой подход (может работать или не работать в зависимости от размера ваших фактических данных / проблемы) - использовать пакет purrr для работы со списками:

> m <- foreach(i=1:3)%do%{create_lists()}
> m
[[1]]
[[1]]$l
[1] 21 33 12 50 36

[[1]]$n
[1] 74


[[2]]
[[2]]$l
[1] 12 80 39 78  6

[[2]]$n
[1] 74


[[3]]
[[3]]$l
[1]  9 61 75 63 94

[[3]]$n
[1] 2


> purrr::transpose(m)
$l
$l[[1]]
[1] 21 33 12 50 36

$l[[2]]
[1] 12 80 39 78  6

$l[[3]]
[1]  9 61 75 63 94


$n
$n[[1]]
[1] 74

$n[[2]]
[1] 74

$n[[3]]
[1] 2

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...