jakub
jakub

Reputation: 5104

Evaluate function call within function call

When I use this with atomic vector, it works:

x = data.frame(myvar = 1:10)

test_atom = function(var, maxvalue = max(var)) { 
    return(maxvalue)
}

test_atom(x$myvar)
# [1] 10

But when I try to evaluate a column in a data frame, there is a problem:

test_df = function(data, var, maxvalue = max(var)) { 
    params = as.list(match.call()[-1])
    data$var = eval(params$var, data)
    return(maxvalue)
}

test_df(x, myvar)
# Error in test_df(x, myvar) : object 'myvar' not found

Note however that the following works ok, so evaluation seems fine:

test_df2 = function(data, var, maxvalue = max(var)) { 
    params = as.list(match.call()[-1])
    data$var = eval(params$var, data)
    return(data$var)
}

test_df2(x, myvar)
# [1]  1  2  3  4  5  6  7  8  9 10

How to properly evaluate the argument so that it detects the maximum value of x$myvar?

EDIT To properly spell out my intention, I want the possibility to set the value for maxvalue manually, but in case I leave it blank, it should set itself to the maximum value of myvar. This could be achieved by a conditional statement within the function to check whether the argument is NULL and then setting the maxvalue to maximum value of myvar within the function - but I wanted to do it in a simpler way, i.e. not within the function.

Example - both should be possible:

test_df(x, myvar, 5) # I set the value of the last argument manually
test_df(x, myvar) # I leave it blank - and it sets itself to the max value of `myvar`

Upvotes: 1

Views: 171

Answers (1)

Tensibai
Tensibai

Reputation: 15784

You can't use a variable with $ subseting, you have to tackle it a little differently.

test_df3 = function(data, var, maxvalue = max(data[,var])) { 
  return(maxvalue)
}

You should pass data (which is your data frame) and subset it by the var value to max, or it won't be able to guess what you're trying to get the max of.

In case var is a column name, it has to be a string or R will try (at the call time) to find a variable/object with this name to give its value to the function.

This gives:

> test_df3(x,'myvar')
[1] 10
> test_df3(x,'myvar',5)
[1] 5

Upvotes: 1

Related Questions