Add a new nested column which is a 2nd data frame filtered by elements in the first

I have two data_frames like so:


df1 <- data_frame(ONE = rep("a", 6),
                  TWO = letters[2:7])

df2 <- data_frame(id = sample(letters[1:7], 80, replace = TRUE),
                  dat1 = rnorm(n = 80, 10, 1),
                  dat2 = rnorm(n = 80, 20, 1))

where the contents of df1 columns ONE and TWO correspond to the id column in df2.

I would like to create a new column in df1 which is a nested column with each row in the column containing a filtered df2 data_frame based on the id values in ONE and TWO.

I was hoping something like this might work:

df1 %>% 
  mutate(new = map2(ONE, TWO, ~ filter(df2, .x, .y)))

but I get:

Error in mutate_impl(.data, dots) :
Evaluation error: Evaluation error: operations are possible only for numeric, logical or complex types

I have been playing around with nest() and map_df() but am making little headway. What should I try next?

2 Likes

How do you want to filter df2 ? Do you have an example for one row of df1 ?
Currently, you did not provide any logical predicate in filter. I think this is why you get the error.

For example, if you want to keep in df2 only in present in ONE or TWO, you can do this:

library(tidyverse)
df1 <- data_frame(ONE = rep("a", 6),
                  TWO = letters[2:7])

df2 <- data_frame(id = sample(letters[1:7], 80, replace = TRUE),
                  dat1 = rnorm(n = 80, 10, 1),
                  dat2 = rnorm(n = 80, 20, 1))
df1 %>% 
  mutate(new = map2(ONE, TWO, ~ filter(df2, .x == id | .y == id)))
#> # A tibble: 6 x 3
#>   ONE   TWO   new              
#>   <chr> <chr> <list>           
#> 1 a     b     <tibble [32 x 3]>
#> 2 a     c     <tibble [27 x 3]>
#> 3 a     d     <tibble [20 x 3]>
#> 4 a     e     <tibble [20 x 3]>
#> 5 a     f     <tibble [25 x 3]>
#> 6 a     g     <tibble [21 x 3]>

Created on 2018-03-12 by the reprex package (v0.2.0).

5 Likes

Awesome, thanks. Had a mental lapse and this helped set me straight.

I believe you could also accomplish this by first joining then nesting. No map required.