переменная списка фильтров в dplyr - PullRequest
0 голосов
/ 29 мая 2018

В общем, как мы фильтруем по переменной списка в dplyr?

Например, фрейм данных, где одна переменная представляет собой список различных классов объектов:

aa <- tibble(ss = c(1,2),
             dd = list(NA,
                       matrix(data = c(1,2,3,4),
                              nrow = 2,
                              ncol = 2)))

> aa
# A tibble: 2 x 2
#     ss dd           
#  <dbl> <list>       
#1  1.00 <lgl [1]>    
#2  2.00 <dbl [2 × 2]>

Например, еслиЯ хочу отфильтровать по логике (хотя может быть что угодно), если бы это был не список, это было бы так просто, как:

aa %>% filter(is.logical(dd))

Но это возвращает

# A tibble: 0 x 2
# ... with 2 variables: ss <dbl>, dd <list>

Поскольку это непервый логический элемент, это первый элемент первого элемента:

> is.logical(aa$dd[1])
# [1] FALSE
> is.logical(aa$dd[[1]])
# [1] TRUE

Можно использовать purrr:map для других операций над переменными вложенного списка, но это также не работает.

> aa %>% filter(map(.x = dd,
+                   .f = is.logical))
# Error in filter_impl(.data, quo) : basic_string::resize

Что мне здесь не хватает?

Ответы [ 2 ]

0 голосов
/ 29 мая 2018

Поскольку 'dd' является столбцом list, мы можем циклически проходить через 'dd', используя map, но каждый элемент 'dd' может иметь более одного элемента, поэтому мы создаем условие, что если all элементы NA, затем filter строки набора данных

library(tidyverse)
aa %>%
   filter(map_lgl(dd, ~ .x %>%
                           is.na %>% 
                             all))
# A tibble: 1 x 2
#     ss dd       
#   <dbl> <list>   
#1     1 <lgl [1]>

Если это примерно filter на основе class.

aa %>%
    filter(map_lgl(dd, is.logical))
# A tibble: 1 x 2
#     ss dd       
#  <dbl> <list>   
#1     1 <lgl [1]>

В коде ОП выводом map по-прежнему является list, мы преобразуем его в логический вектор с map_lgl

0 голосов
/ 29 мая 2018

Лучшее, что я могу сделать, - создать фиктивную переменную, используя is.logical с purrr:map, unlist it, filter, затем un- select фиктивная переменная.Работает, но что за суета.

aa %>%
  mutate(ff = map(.x = dd,
                       .f = is.logical),
         ff = unlist(ff)) %>%
  filter(ff == TRUE) %>%
  select(-ff)

# A tibble: 1 x 2
#      ss dd       
#   <dbl> <list>   
# 1  1.00 <lgl [1]>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...