Reputation: 11
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
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
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
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