#r #nested #nested-lists #tibble
#r #вложенный #вложенных списков #tibble
Вопрос:
Когда у меня есть данные, содержащие вложенные списки внутри, я хочу изменить новые столбцы на определенном уровне, обусловленном значениями, существующими на более глубоких вложенных уровнях. В частности, вложенный объект представляет собой именованный список, и я хочу проверить имена этого списка, чтобы сделать вывод о том, существует ли информация в данных или нет.
РЕДАКТИРОВАТЬ — я заменил данные в моем примере
Хотя ответ @Ronak действительно ответил на мой вопрос с данными, указанными изначально, я понял, что допустил ошибку, и пример данных toy неверно отражает структуру моих данных. Ниже приведены данные, которые правильно отражают мою ситуацию.
library(tibble)
df_correct <-
structure(
list(
var_name = c("age", "classes"),
title = c("What is your age?",
"what classes have you taken?"),
class_descriptions = list(
NULL,
list(
History = "History of Art",
Chemistry = "Organic Chemistry",
other = "Other Classes"
)
)
),
row.names = c(NA,-2L),
class = c("tbl_df",
"tbl", "data.frame")
)
## # A tibble: 2 x 3
## var_name title class_descriptions
## <chr> <chr> <list>
## 1 age What is your age? <NULL>
## 2 classes what classes have you taken? <named list [3]> <--- this list is what I need to check against
df_correct %>%
unnest_wider(class_descriptions)
## # A tibble: 2 x 5
## based on whether
## "History" exists
## ↓
## var_name title History Chemistry other
## <chr> <chr> <chr> <chr> <chr>
## 1 age What is your age? NA NA NA
## 2 classes what classes have you taken? History of Art Organic Chemistry Other Classes
Итак, учитывая df_correct
, и не обязательно используя unnest_wider
(это было просто для того, чтобы показать структуру вложенных данных), как я могу изменить новый столбец, df_correct
чтобы учесть, появляется ли в нем «История» class_descriptions
?
Желаемый результат — обновлен
# A tibble: 2 x 4
var_name title class_descriptions has_taken_history
<chr> <chr> <list> <lgl>
1 age What is your age? <NULL> NA
2 classes what classes have you taken? <named list [3]> TRUE
Подробнее о желаемом решении (а не о выходе)
Я надеюсь при публикации этого вопроса найти способ добавить еще один столбец df_correct
для определения того, существует ли строка в именах именованного списка class_descriptions
. Другими словами, я ищу решение, которое потребует только 2 входных данных:
- Что искать (в данном примере строка
"History"
) - Где искать (в данном примере имена именованного списка
class_descriptions
, который вложен вdf_correct
).
Если строка найдена, заполните TRUE
новый столбец в df_correct
, в противном случае заполните FALSE
.
Ответ №1:
Редактировать 2
df_correct %>%
mutate(has_taken_history = map_lgl(class_descriptions,
~'History' %in% names(.x)))
# var_name title class_descriptions has_taken_history
# <chr> <chr> <list> <lgl>
#1 age What is your age? <NULL> FALSE
#2 classes what classes have you taken? <named list [3]> TRUE
Редактировать 1
Для отредактированных данных вы можете сделать :
library(tidyverse)
df_correct %>%
mutate(class_descriptions1 = class_descriptions) %>%
unnest_wider(class_descriptions) %>%
mutate(across(History:other, ~ifelse(is.na(.), NA, TRUE))) %>%
dplyr::select(var_name, title, class_descriptions = class_descriptions1, has_taken_history = History)
# var_name title class_descriptions has_taken_history
# <chr> <chr> <list> <lgl>
#1 age What is your age? <NULL> NA
#2 classes what classes have you taken? <named list [3]> TRUE
Вы можете сохранить только те объекты, которые вам нужны, из выходных данных.
Оригинальный ответ
Вы можете использовать map_lgl
для возврата логического вектора :
df %>%
unnest_wider(info) %>%
mutate(has_taken_history = map_lgl(classes_taken, ~"History" %in% .x),
has_taken_chemistry = map_lgl(classes_taken, ~"Chemistry" %in% .x))
# student_name location year_born classes_taken has_taken_history has_taken_chemistry
# <chr> <chr> <dbl> <list> <lgl> <lgl>
#1 John San Francisco 2000 <chr [4]> TRUE FALSE
#2 Sarah Miami 2002 <chr [4]> TRUE TRUE
Более общим решением для всех субъектов было бы обращение к unnest
субъектам и получение данных в широком формате.
df %>%
unnest_wider(info) %>%
unnest(classes_taken) %>%
mutate(value = TRUE) %>%
pivot_wider(names_from = classes_taken, values_from = value, values_fill = FALSE)
# student_name location year_born Astronomy Cosmology History Robotics Chemistry Biology Zoology
# <chr> <chr> <dbl> <lgl> <lgl> <lgl> <lgl> <lgl> <lgl> <lgl>
#1 John San Francisco 2000 TRUE TRUE TRUE TRUE FALSE FALSE FALSE
#2 Sarah Miami 2002 FALSE FALSE TRUE FALSE TRUE TRUE TRUE