Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass a condition as a function parameter

Tags:

r

Is there a way to pass in a condition as a parameter? For example:

#g is some data'

getIndexesWhen <- function (colname, condition) {
    a <- as.vector(g[,colname])
    a <- which(a fits condition)
}

And then be able to pass in the condition itself, e.g. call something like getIndexesWhen('GDP','> 435'). Or do I need to have separate functions for each case, e.g. =, !=, >, <, etc.?

like image 530
JoshDG Avatar asked Dec 19 '16 19:12

JoshDG


3 Answers

Instead of using an expression or function for "greater than 435", you could split up the "greater than" part and the "435" part as arguments to your getIndexesWhen function:

getIndexesWhen <- function(colname, fxn, rhs) {
  which(fxn(as.vector(g[,colname]), rhs))
}

Now you can get the functionality you want without needing to declare a user-defined function for every function/right hand side pairing:

g <- iris
getIndexesWhen("Petal.Width", `<`, 0.2)
# [1] 10 13 14 33 38
getIndexesWhen("Petal.Length", `==`, 1.5)
# [1]  4  8 10 11 16 20 22 28 32 33 35 40 49
like image 85
josliber Avatar answered Oct 13 '22 09:10

josliber


You may pass a function as a parameter:

getIndexesWhen<-function(colname, condition)
{
    a<-as.vector(g[,colname])
    return(which(condition(a)))
}

getIndexesWhen("GDP", function(x)x>435)
like image 25
user31264 Avatar answered Oct 13 '22 08:10

user31264


Since you can convert a string to an executable expression using e.g.,:

eval(parse(text = "3 > 1"))

Or, a string vector of executable expressions using e.g.,:

sapply(parse(text = paste0(3:4, "<4")), eval)

You could exploit this in your case to pass a free text condition by using:

getIndexesWhen<-function(g, colname, condition)
{
  a <- as.vector(g[,colname])
  which(sapply(parse(text = paste0(a, condition)), eval))
}

This evaluates the column vector against the provided condition.

g <- data.frame(C1 = c(2, 3, 4))
getIndexesWhen(g, "C1", ">=3")
like image 20
Thom Quinn Avatar answered Oct 13 '22 08:10

Thom Quinn