Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to filter a dataframe with a character vector

Tags:

r

filter

dplyr

I'm trying to filter a data.frame with filter() function from the package dplyr. The main problem here is that I want to use a vector for the conditions.

For example

library(dplyr)
conditions <- c("Sepal.Width<3.2","Species==setosa")
DATA <- iris %>%
  filter(conditions) #This doesnt work, of course.

Is there any function that would take

conditions <- c("Sepal.Width<3.2","Species==setosa")

as an input and give me

Sepal.Width<3.2 & Species==setosa

as an output? I though about using eval(parse...) with sapplyand maybe paste0() to add the &, but can't make it work.

Any help would be aprecciated.

like image 778
kowa Avatar asked Jan 25 '23 16:01

kowa


1 Answers

There are multiple issues. First, you need to quote inside quotation for the second condition:

conditions <- c("Sepal.Width < 3.2", "Species == 'setosa'")

Then, you need to specify the association between the two conditions. Here, I assumed an &. Then you can use eval(parse(...)):

iris %>%
 filter(eval(parse(text = paste(conditions, sep = "&"))))

   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1           5.1         3.5          1.4         0.2  setosa
2           4.9         3.0          1.4         0.2  setosa
3           4.7         3.2          1.3         0.2  setosa
4           4.6         3.1          1.5         0.2  setosa
5           5.0         3.6          1.4         0.2  setosa
6           5.4         3.9          1.7         0.4  setosa
7           4.6         3.4          1.4         0.3  setosa
8           5.0         3.4          1.5         0.2  setosa
9           4.4         2.9          1.4         0.2  setosa
10          4.9         3.1          1.5         0.1  setosa

On the other hand, I think it is always important to quote @Martin Mächler to warn about the potential problems associated with this approach:

The (possibly) only connection is via parse(text = ....) and all good R programmers should know that this is rarely an efficient or safe means to construct expressions (or calls). Rather learn more about substitute(), quote(), and possibly the power of using do.call(substitute, ......).

like image 186
tmfmnk Avatar answered Feb 13 '23 20:02

tmfmnk