I have a reprex as follows:
library(dplyr)
library(purrr)
df1 <- data.frame(
col1 = 1:5,
col2 = 6:10
)
df2 <- df1 %>%
mutate(col3 = 1:5)
ls <- list(
a = list(df1 = df1),
b = list(
df1 = df1,
df2 = df2
),
c = list(
df2 = df2
)
)
I want to filter ls
so that elements of ls
that contain col3
by name are kept.
I have tried using keep but I am unable to index correctly at the right depth.
Expected solution:
list(
b = list(
df2 = df2
)
,c = list(
df2 = df2
)
)
This is close:
ls %>%
map(
~keep(.x, ~ "col3" %in% names(.x))
)
I know you ask for purrr
, but here's a convenient one-liner with rrapply
.
rrapply
is based on base R rapply
and aims at applying functions recursively to a set of elements of a list. Here, I use the condition
argument to specify which elements should be evaluated, and how = "prune"
to remove any elements that are not matching the condition. classes = "data.frame"
specifies that the condition
function should be applied at the level of the data.frame
(and not, for instance, at the levels of the columns of the data.frames).
library(rrapply)
rrapply(ls, condition = \(x) "col3" %in% names(x), classes = "data.frame", how = "prune")
# $b
# $b$df2
# col1 col2 col3
# 1 1 6 1
# 2 2 7 2
# 3 3 8 3
# 4 4 9 4
# 5 5 10 5
#
#
# $c
# $c$df2
# col1 col2 col3
# 1 1 6 1
# 2 2 7 2
# 3 3 8 3
# 4 4 9 4
# 5 5 10 5