Haezer
Haezer

Reputation: 476

How to use dplyr::filter inside purrr::map

I have a data.frame with several variables. I would like to get a list where each item is a variable of the data.frame filtered with a condition.

For example, let's say I have something like this:

df <- tribble(
  ~ var1, ~ var2, ~ var3,
  4, 0, 0,
  2, 3, 1,
  0, 4, 0
  )
#    var1  var2  var3
#   <dbl> <dbl> <dbl>
# 1     4     0     0
# 2     2     3     1
# 3     0     4     0

And I want to get the list of the variable filtered >0

# $var1
# [1] 4 2
#
# $var2
# [1] 3 4
#
# $var3
# [1] 1

I tried several things but the closest I can get for now is something like

df %>% map(~filter(df, .>0))

and I would like to include a dplyr::select to get only the variable filtered. But I can't figure out how to do that.

Thanks for help and sorry for bad English, I hope it's still understandable.

Upvotes: 1

Views: 3718

Answers (2)

akrun
akrun

Reputation: 886938

We can loop through the names. Note that filter expects a data.frame/tbl_df. With map, we are looping through the columns and it is a vector. So, in order to make filter work, map through the names, subset the column, apply the filter and unlist

map(names(df), ~ df %>% 
                  select(.x) %>%
                  filter(. >0) %>%
                  unlist(., use.names = FALSE))

Or with split

split.default(df, names(df)) %>%
            map(~  .x %>% 
                       filter(. > 0) %>%
                        pull(1))

NOTE: The OP's question is How to use dplyr::filter inside purrr::map


Other ways without using dplyr::filter are

map(df, ~ keep(.x, .x != 0))

Or

map(df, setdiff, 0)

Or

map(df, ~ discard(.x, .x == 0))

Or using base R

lapply(df, setdiff, 0)
#$var1
#[1] 4 2

#$var2
#[1] 3 4

#$var3
#[1] 1

Upvotes: 3

Ronak Shah
Ronak Shah

Reputation: 388807

Using purrr::map we can do

purrr::map(df, ~.[.!= 0])

#$var1
#[1] 4 2

#$var2
#[1] 3 4

#$var3
#[1] 1

Base R approach with lapply could be

lapply(df, function(x) x[x!= 0])

Upvotes: 2

Related Questions