Вставить вложенный список data.frames в R

77
7

Настроить:

У меня есть тибет (названные данные) со встроенным списком data.frames.

df1 <- data.frame(name = c("columnName1","columnName2","columnName3"),
value = c("yes", 1L, 0L),
stringsAsFactors = F)

df2 <- data.frame(name = c("columnName1","columnName2","columnName3"),
value = c("no", 1L, 1L),
stringsAsFactors = F)

df3 <- data.frame(name = c("columnName1","columnName2","columnName3"),
value = c("yes", 0L, 0L),
stringsAsFactors = F)

responses = list(df1,
df2,
df3)

data <- tibble(ids = c(23L, 42L, 84L),
responses = responses)

Обратите внимание, что это упрощенный пример данных. Исходные данные jsonlite::stream_in() из плоского файла json и загружены jsonlite::stream_in().

Задача:

Моя цель состоит в том, чтобы преобразовать этот заголовок в другой кусочек, где внедренные data.frames распространяются (транспонируются) как столбцы; например, моя цель состоит в следующем:

goal <- tibble(ids = c(23L, 42L, 84L),
columnName1 = c("yes","no","yes"),
columnName2 = c(1L, 1L, 0L),
columnName3 = c(0L, 1L, 0L))

# goal tibble
> goal
# A tibble: 3 x 4
ids columnName1 columnName2 columnName3
<int> <chr> <int> <int>
1 23 yes 1 0
2 42 no 1 1
3 84 yes 0 0

Мое неэлегантное решение:

Используйте dplyr::bind_rows() и tidyr::spread():

rdf <- dplyr::bind_rows(data$responses, .id = "id") %>%
tidyr::spread(key = "name", -id)

goal2 <- cbind(ids = data$ids, rdf[,-1]) %>%
as.tibble()

Сравнивая мое решение с целью:

# produced tibble
> goal2
# A tibble: 3 x 4
ids columnName1 columnName2 columnName3
* <int> <chr> <chr> <chr>
1 23 yes 1 0
2 42 no 1 1
3 84 yes 0 0

В целом, мое решение работает, но имеет несколько проблем:

Я не знаю, как передать уникальные идентификаторы через bind_rows() что заставляет меня создать фиктивный id ("id"), который не может соответствовать исходному id ("id"). Это заставляет меня использовать cbind() (что мне не нравится) и вручную удалять фиктивный id (с использованием -1 нарезки на rdf).

Формат столбцов теряется, так как мой подход преобразует целые столбцы в символы.

Любые предложения по улучшению моего решения (особенно с использованием пакетов на основе tidyverse, таких как tidyjson или tidyr)?

спросил(а) 2021-01-19T16:00:10+03:00 6 месяцев, 1 неделя назад
1
Решение
78

Мы можем перебрать столбец "ответы" с помощью map, spread его на "широкий" с помощью convert = TRUE чтобы типы столбцов создавали это как столбец с transmute а затем без unnest

library(tidyverse)
data %>%
transmute(ids, ind = map(responses, ~.x %>%
spread(name, value, convert = TRUE))) %>%
unnest
# A tibble: 3 x 4
# ids columnName1 columnName2 columnName3
# <int> <chr> <int> <int>
#1 23 yes 1 0
#2 42 no 1 1
#3 84 yes 0 0

Или используя код OP, мы устанавливаем имена list с столбцом "идентификаторы", делаем bind_rows и затем spread

bind_rows(setNames(data$responses, data$ids), .id = 'ids') %>% 
spread(name, value, convert = TRUE)

ответил(а) 2021-01-19T16:00:10+03:00 6 месяцев, 1 неделя назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема