I can enter something like
list(3, 4, 5, 4, 3, 2, 2, 3, 2, 3, 4, 1, 1, 2, 1, 3) == 3
and get back
TRUE FALSE FALSE FALSE TRUE FALSE FALSE TRUE FALSE TRUE FALSE FALSE FALSE FALSE FALSE TRUE
which is great because it means that I don't have to clumsily use lapply()
to get R to do what I want. But what if I have a list of lists, where the inner lists have named elements. For example, I could have a list of books, where each book is a list consisting of a $title
and a $year
in which it was published. Let's say I have a tibble called books
with just 1 column called book
that is this list of books. How would I filter for only books published before 2000, or mutate()
a column containing the titles?
The naive approach I would take to trying to filter by year is:
filter(books, book$year < 2000)
because I want it to go through each element of books$book
and then look at the $year
element of that, but, since books$book
is itself a list, R looks for something named books$book$year
instead of looking for the $year
element of each element inside of books$book
. How do I get around this without using lapply()?
Just for completeness, here is the (somewhat clumsy looking) way I do it with lapply():
filter(books, as.logical(lapply(books$book, function(x) x$year < 2000)))
CodePudding user response:
You can use the code that you provide above, but you can simplify it to this:
filter(books,sapply(book, \(x) x$year<2000))
Instead of
filter(books, as.logical(lapply(books$book, function(x) x$year < 2000)))
The two changes are:
- use
sapply()
instead oflapply()
which will obviate the need foras.logical()
- use the
\(x)
shortcut forfunction(x)
If you really don't want to use lapply/sapply, you can, as @akrun suggests, switch to map_lgl
, although with a slight simplification:
filter(books, map_lgl(book,~x$year<2000))