Продвинутый unnest и его неизвестные аргументы
При парсинге сложных списков, полученных в виде ответа от различных API я зачастую использую функции tidyr::unnest_longer() и unnest_wider().
Все пакеты входящие в tidyverse имеют шикарную, наверное лучшую, документацию. Все функции имеют детальное описание, и огромное количество примеров кода их использования. Но в функциях разворачивания списков, таких как hoist(), unnest_longer() и unnest_wider(), есть несколько аргументов, которые имеют лишь краткое описание, но примеров их использования нет. Да и мои попытки нагуглить варианты их использования не увенчались успехом.
Ниже мы разберём аргументы ptype и transform доступные в unnest_*() функциях.
Описание аргументов:
● transform, .transform - Необязательный аргумент, принимает именованный список функций преобразования, применяемых к каждому компоненту. Используйте эту функцию, если вы хотите преобразовать или проанализировать отдельные элементы по мере их разворачивания.
● ptype, .ptype - Необязательный аргумент, принимает именованный список прототипов, объявляющий желаемый тип вывода каждого компонента. Используйте этот аргумент, если вы хотите проверить, что каждый элемент имеет типы, которые вы ожидаете при разворачивании списка.
Примеры использования:
Для начала сгенерируем тестовый набор данных:
# тестовый список
test_list <- list(
list(name = 'John',
age = '37',
children = list('Paul', 'Ron')),
list(name = 'Tim',
age = '25',
children = list('Liza'))
)
Пробуем развернуть этот список, не используя дополнительные аргументы:
# первая попытка развёртывания
tibble(uncol = test_list) %>%
unnest_wider(uncol)
# A tibble: 2 x 3
name age children
<chr> <chr> <list>
1 John 37 <list [2]>
2 Tim 25 <list [1]>
Какие проблемы мы можем решить с помощью аргументов ptype и transform
Итак, вроде мы развернули наш список, но появилось две проблемы, которые далее мы исправим.
1. Возраст в поле age является текстом, требуется привести его к целочисленному типу.
2. Поле children по прежнему является списком, а нам необходимо сделать так, что бы имена детей, были перечислены в одной ячейке через запятую.
Аргумент ptype
ptype позволяет вам добавить проверку типов данных, выходящего тиббла, например в следующем примере мы добавим проверку поля age.
# добавляем проверку типа данных в поле age
tibble(uncol = test_list) %>%
unnest_wider(
uncol,
ptype = list(age = 2)
)
Error: Can't convert <character> to <double>.
Сообщение об ошибке малоинформативное, но суть не меняется, мы проверяем тип данных в указанных полях , и если какое то из полей не соответствует указанному прототипу - мы получим ошибку.
Прототип - это просто образец данных нужного типа, если мы хотим убедиться, что какое то поле является целым числом, то необходимо в качестве прототипа передать любое целое число, я использовал 2, но вместо него можно передать любое другое целое число.
Аргумент transform
Аргумент transform позволит нам решить описанные ранее проблемы, а именно:
1. Преобразовать поле age в целочисленный тип.
2. Объединить элементы вложенного поля children через запятую, избавившись от вложенности.
# используем ptype и transform
tibble(uncol = test_list) %>%
unnest_wider(
uncol,
transform = list(
children = function(x) paste(x, collapse = ', '),
age = as.integer),
ptype = list(age = 2),
)
# A tibble: 2 x 3
name age children
<chr> <dbl> <chr>
1 John 37 Paul, Ron
2 Tim 25 Liza
Ссылки:
- видео урок по работе с функциями разворачивания списков
- перевод виньетки "Rectangling"
#заметки_по_R