googledrive 4: Как фильтровать дриблинг (диск-тиббл), применяя критерии к вложенному списку в тиббле?

#r #tidyverse #tibble #nested-tibble

Вопрос:

С помощью пакета googledrive4 доступ к файлам на Google диске удивительно прост.

 p_load(googledrive4, tidyverse)
dribble1 <- drive_ls()

> dribble1
# A dribble: 2000 × 3
  name           id                                drive_resource   
  <chr>          <drv_id>                          <list>           
1 somefile1.zip  1w76E2ze0p00jtxxxxxxxxxxxxxxxxxxx <named list [37]>
2 somefile2.zip  1Zau_jwYlDHFK4xxxxxxxxxxxxxxxxxxx <named list [37]>
...
 

однако я изо всех сил пытаюсь отфильтровать результат на основе параметров, вложенных в именованный список «drive_resource».
Я хочу, например, отфильтровать по дате и времени, чтобы создать дриблинг, содержащий только файлы, сохраненные после определенной даты.

в отчаянии и после многих попыток и ошибок я добился того, чего хотел, за 2 шага, подобных этому:

 p_load(tidyverse, lubridate)

# 1 - unnest to make a list of ID's that match my criteria
range <- interval(as_date("2021/1/1", now())

filtered_list <- dribble1 %>%
  unnest_longer(col = drive_resource) %>%
  filter(drive_resource_id == "modifiedTime") %>%
  unnest_longer(drive_resource, values_to = "modtime") %>%
  mutate(modtime = as_datetime(modtime)) %>%
  filter(modtime %within% range)

# 2 - filter the original dribble with filtered list of ID's
result_dribble <- dribble1 %>%
  filter(id %in% filtered_list$id)
 

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

Не мог бы кто-нибудь, пожалуйста, пролить свет на это?

(извините за отсутствие reprex. капли построены уникальным способом, который я еще не до конца понимаю, и не смог использовать datapasta для восстановления капли, содержащей вложенный именованный список)

выше приведен упрощенный пример, данные, которые я обрабатываю, намного больше, я надеюсь, что скриншот из RStudio имеет смысл для людей, не знакомых с googledrive 4.

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

Ответ №1:

После ночи размышлений я нашел решение в hoist()

 dribble1 %>% 
  hoist(drive_resource, "modifiedTime") %>%
  mutate(modifiedTime = as_datetime(modifiedTime)) %>%
  filter(modifiedTime %within% range)
 

Теперь мой код намного короче и выполняется мгновенно!

как побочный узел, сначала я изо всех сил пытался использовать unnnest_wider его , но столкнулся с ошибкой.

 > dribble1 %>% unnest_wider(col = drive_resource) 
Error: Names must be unique.
x These names are duplicated:
  * "name" at locations 1 and 6.
  * "id" at locations 2 and 5.
ℹ Use argument `names_repair` to specify repair strategy.
 

это было легко исправлено с помощью аргумента names_repair.

 > dribble1 %>% unnest_wider(col = drive_resource, names_repair = "unique") 
 

Это было предпочтительнее, чем unnest_longer (), так как он сохраняет строки.