Purrr::map com filtro

Boa tarde a todos e todas!

Procurei aqui no forum e no stackoverflow e ainda não consegui uma boa solução. A questão é que quero fazer um filtro em um purr::map(). No exemplo abaixo, eu tenho uma estrutura de listas. No primeiro comando, eu consigo aplicar o map() no atributo “nota”. Mas como eu devo fazer se quiser mapear apenas as notas quando outro atributo atende um critério? Tento fazer isso no segundo comando mas, como podem ver na saída, o filtro não funcionou. Agradeço qualquer ajuda =)

library(purrr)
library(magrittr)
#> Warning: package 'magrittr' was built under R version 4.0.5
#> 
#> Attaching package: 'magrittr'
#> The following object is masked from 'package:purrr':
#> 
#>     set_names
foo <- list(turma = list(grupo=c(nome="A",nota=7.0),
                         grupo=c(nome="B",nota=8.3),
                         grupo=c(nome="A",nota=7.9),
                         grupo=c(nome="B",nota=8.1)))
foo %>% 
  pluck("turma") %>% 
  map("nota")
#> $grupo
#> [1] "7"
#> 
#> $grupo
#> [1] "8.3"
#> 
#> $grupo
#> [1] "7.9"
#> 
#> $grupo
#> [1] "8.1"

foo %>% 
  pluck("turma") %>% 
  map("nota", dplyr::filter, nome == "A")
#> $grupo
#> [1] "7"
#> 
#> $grupo
#> [1] "8.3"
#> 
#> $grupo
#> [1] "7.9"
#> 
#> $grupo
#> [1] "8.1"

Created on 2021-07-26 by the reprex package (v2.0.0)

Infelizmente o filter() não funciona para listas ainda :frowning: Lembre-se também que o map() recebe uma lista e uma função! No caso do seu segundo código, qual é a função? Você está passando "nota", dplyr::filter, nome == "A", mas esses três juntos não geram uma função.

Sendo assim, minha sugestão é usar o keep() (equivalente do filter() para listas) antes do map(). Veja se o exemplo abaixo resolve o seu problema:

library(purrr)
library(magrittr)

foo <- list(turma = list(grupo=c(nome="A",nota=7.0),
                         grupo=c(nome="B",nota=8.3),
                         grupo=c(nome="A",nota=7.9),
                         grupo=c(nome="B",nota=8.1)))

foo %>% 
  pluck("turma") %>% 
  keep(~.x[1] == "A") %>%
  map("nota")
#> $grupo
#> [1] "7"
#> 
#> $grupo
#> [1] "7.9"

Created on 2021-07-26 by the reprex package (v2.0.0)

1 curtida

Resolve sim, Caio! Era exatamente esse tipo de função que eu precisava. Já apliquei o keep aqui e funcionou bem. Muito obrigado!!