tags:

views:

67

answers:

2

I am building a gui which lets me select a subset of a data.frame by clicking on the various factor names. After having received user input, how do i pass it to the subset function?

e.g.: I have a dataframe df with factors MORNING and EVENING in column timeofday and RECEIVE and SEND in column optype. From the GUI I know that the user wants to a subset containing only RECEIVE operations, so i have the following strings as well:

RequestedFactor1 which equals "optype"
RequestedRelationship1 equals "=="
RequestedValue1 which equals "RECEIVE"

What can i do to those strings to pass them to subset, so that I will receive the same output as if i had called subset(df,optype=="RECEIVE") ?

TIA

+2  A: 

For this you can use an eval-parse construct, but again I warn that this is actually tricky business. Please read the help files about these two very carefully. So in your case this becomes :

subset(df,eval(parse(text=paste(RF1,RR1,RV1)))) 

An example to illustrate some tricky parts :

> RF1 <- "optype"

> RR1 <- "=="

> RV1 <- "\"RECEIVE\""

> optype <- c("RECEIVE","Not")

> ifelse(eval(parse(text=paste(RF1,RR1,RV1))),1,0)
[1] 1 0

Mind the escaped quote-marks (\"). This is necessary as you want to test against a string, and not the RECEIVE object. Alternatively you can do :

> RF1 <- "optype"

> RR1 <- "=="

> RV1 <- "Text"

> optype <- c("RECEIVE","Not")

> Text <- "RECEIVE"

> ifelse(eval(parse(text=paste(RF1,RR1,RV1))),1,0)
[1] 1 0
Joris Meys
Thank You! Should have thought of it.
+3  A: 

The comparison operators in R are actually special functions, so you can use do.call to run the functions, no need for eval and parse and the potential headaches that can come from there. e.g.:

rf1 <- 'Species'
rr1 <- '=='
rv1 <- 'setosa'

subset(iris, do.call(rr1, list( get(rf1), rv1 ) ) )

You need to "get" the variable so that you have the variable value rather than the name, the rest can be the character strings.

Greg Snow
Not real need to use subset at all - `iris[match.fun(rr1)(iris[[rf1]], rv1), ]`
hadley
`match.fun` is much cleaner than the accepted answer.
Vince
thx gentlemen, I'm learning myself as well.
Joris Meys