siddu479
siddu479

Reputation: 11

Using logical operators stored in character variables while subsetting data frame in R

My R script get three inputs from user which are read into var1, var2 and var3.

I am trying to perform a simple subset operation for data frame. The pseudocode of my thinking is shown below:

subset_data_frame<- dat[ dat[[var1]] var2 var3 , ]

where     var1= column name from dat
          var2= can be any of the logical operator like '==', '>', '<' etc.
          var3= numeric value    

But this doesn't work because of the way I used the logical operator from var2.

Please suggest me an alternate way to get out of this problem.

Upvotes: 1

Views: 968

Answers (3)

Rich Scriven
Rich Scriven

Reputation: 99331

If the user is entering these variables as characters, then you'll need to create and evaluate a call. Here's an example using the mtcars data set:

var1 <- "mpg"
var2 <- ">"
var3 <- "30"

expr <- call(var2, mtcars[[var1]], as.numeric(var3))

## or you could also construct a function call with substitute()
# expr <- substitute(
#     FUN(mtcars[[column]], value), 
#     list(FUN = as.name(var2), column = var1, value = as.numeric(var3))
# )

Now we have created an unevaluated call expr which can then be evaluated with eval

mtcars[eval(expr),]
#                 mpg cyl disp  hp drat    wt  qsec vs am gear carb
# Fiat 128       32.4   4 78.7  66 4.08 2.200 19.47  1  1    4    1
# Honda Civic    30.4   4 75.7  52 4.93 1.615 18.52  1  1    4    2
# Toyota Corolla 33.9   4 71.1  65 4.22 1.835 19.90  1  1    4    1
# Lotus Europa   30.4   4 95.1 113 3.77 1.513 16.90  1  1    5    2

Upvotes: 1

B.Mr.W.
B.Mr.W.

Reputation: 19628

(1) Regular Expression

You first need to construct a legit expression based on user's input and then evaluate that string as a command. Here is a POC.

> cmd <- "iris[iris$1% 2% 3%,]"
> columnname <- readline("columnname:")
columnname:Sepal.Length
> operator <- readline("operator:")
operator:<
> value <- readline("value:")
value:5
> cmd <- gsub("1%", columnname, cmd)
> cmd <- gsub("2%", operator, cmd)
> cmd <- gsub("3%", value, cmd)
> cmd
[1] "iris[iris$Sepal.Length < 5,]"
> eval(parse(text=cmd))
Sepal.Length Sepal.Width Petal.Length Petal.Width    Species
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
7            4.6         3.4          1.4         0.3     setosa
9            4.4         2.9          1.4         0.2     setosa
10           4.9         3.1          1.5         0.1     setosa
12           4.8         3.4          1.6         0.2     setosa
13           4.8         3.0          1.4         0.1     setosa
...

(2) Metaprogram

Here is a chapter - Expressions from HadleyWickham's advanced R. In there, he explains the ins-and-outs of how to program "program".

Upvotes: 0

Anurag Priyadarshi
Anurag Priyadarshi

Reputation: 1109

Step1. make a character vector of the desired expression:

expr<-paste(dat[[var1]],var2,var3,sep = " ")

Step2. evaluate the expression to make a logical vector

myLogicalVec<-sapply(expr, function(x) eval(parse(text=x)))

Step3. use that logical vector in your data frame

dat[myLogicalVec,]

I am fairly new to R and there can be optimal ways of doing it. This is somewhat similar to Richard Scriven's answer but my thought process went like this.

Upvotes: 0

Related Questions