Как экспортировать значения из списка списков во фрейм данных? - PullRequest
0 голосов
/ 03 августа 2020

У меня очень сложная структура, см. Pi c ниже. Я долго борюсь с этой проблемой, и мне очень нужна помощь.

введите описание изображения здесь

Вот пример кода, чтобы мой вопрос был более воспроизводимым

t <- list(
list(answers = list(list(values = "male"),
                   list(values = "6"),
                   list(values = "9"),
                   list(values = "9"),
                   list(values = "other"))
 ),
list(answers = list(list(values = "145")
                  )
)

Мне нужны значения, которые находятся в answers (из каждого списка).

Мне нужно, чтобы это выглядело как фрейм данных - каждый список является столбцом (переменной), и каждое значение 1-го списка в answers, очевидно, является значением. Как это

> d <- data.frame("1" = "male", "2" = 6,
+                 "3" = 9, "4.1" = 9,
+                 "4.2" = 8,
+                 "5" = "other",
+                 "6" = 145)
> d

    X1 X2 X3 X4  X5   X6
1 male 6  9  9  other 145

Другая проблема заключается в том, что значения в первом списке answers могут содержать несколько значений . И я действительно не знаю, как с этим справиться, так как мне нужно точно присвоить переменным их значения.

Итак, я не могу представить, как это получить. Интуитивно я думаю, что lapply() может мне помочь, но я не знаю, как его правильно использовать.

Ответы [ 2 ]

1 голос
/ 04 августа 2020

Использование ваших данных образца:

results = unlist(lapply(t, "[[", "answers"))
names(results) = paste0("X", seq_along(results))
results = as.data.frame(t(results))
#     X1 X2 X3 X4    X5  X6
# 1 male  6  9  9 other 145

Здесь числа относятся к классу character, вы можете использовать type.convert(results), который преобразует их в числа (хотя он также преобразует оставшиеся строки в factor с).

1 голос
/ 04 августа 2020

Хитрый. Вот мои мысли. Кроме того, не очень полезно не предоставлять dput ваших данных.

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

test <- list(
  list(
    answers = list(
      values = list("6", "8", "4", "11", "18"),
      question = list("some_text_1", "some_text_2", "some_text_3"))
    ),
  list(
    answers = list(
      values = list("male"),
      question = list("some_text_4", "some_text_5", "some_text_6"))
  )
  )
)

С некоторые усилия я могу сделать это:

l1 <- lapply(test, function(x) lapply(x,`[[`, 1))
l2 <- unlist(l1, recursive = FALSE)
l3 <- unlist(l2, recursive = FALSE)

С таким результатом:

> l3
$answers1
[1] "6"

$answers2
[1] "8"

$answers3
[1] "4"

$answers4
[1] "11"

$answers5
[1] "18"

$answers
[1] "male"

Или проще:

unlist(l1)

Но последний теряет структуру и все values векторы заканчиваются как один символьный вектор. В вашем списке, я думаю, это даст вам все values векторов на 3-м уровне вложенности в виде списка с элементами неравной длины. Поскольку ваши values векторы имеют неравную длину, я, вероятно, не буду пытаться принуждать это к кадру данных. Это достаточно близко?

ОБНОВЛЕНИЕ

Теперь, обновив набор данных, мы можем сделать:

l1 <- lapply(t, `[[`, 1)
l2 <- unlist(l1, recursive = FALSE)
df <- as.data.frame(l2)

с этим выводом:

> df
  values values.1 values.2 values.3 values.4 values.5
1   male        6        9        9    other      145
...