0 votes
1 view
in R Programming by (5k points)

I'm trying to write a function to accept a data.frame (x) and a column from it. The function performs some calculations on x and later returns another data.frame. I'm stuck on the best-practices method to pass the column name to the function.

The two minimal examples fun1 and fun2 below produce the desired result, being able to perform operations on x$column, using max() as an example. However, both rely on the seemingly (at least to me) inelegant

  • call to substitute() and possibly eval()
  • the need to pass the column name as a character vector.

fun1 <- function(x, column){

  do.call("max", list(substitute(x[a], list(a = column))))

}

fun2 <- function(x, column){

  max(eval((substitute(x[a], list(a = column)))))

}

df <- data.frame(B = rnorm(10))

fun1(df, "B")

fun2(df, "B")

I would like to be able to call the function as fun(df, B), for example. Other options I have considered but have not tried:

  • Pass column as an integer of the column number. I think this would avoid substitute(). Ideally, the function could accept either.
  • with(x, get(column)), but, even if it works, I think this would still require substitute
  • Make use of formula() and match.call(), neither of which I have much experience with.

Subquestion: Is do.call() preferred over eval()?

1 Answer

0 votes
by (24.7k points)

To achieve the desired output, you can directly pass the column name to the function, and you can also pass the desired function as an argument of the function call. There's no need to use substitute, eval, etc

For example:

df <- data.frame(A=5:10, B=6:11, C=7:12)

 fun1 <- function(x, column){

   max(x[, column])

 }

Column name as an argument:

fun1(df, "B")

[1] 11

fun1(df, c("B","A"))

[1] 11

Function as an argument:

df <- data.frame(A=5:10, B=6:11, C=7:12)

 fun1 <- function(x, column, fun){

   fun(x[,column])

 }

fun1(df, "B", max)

[1] 11

You can also use the [[ operator as follows:

fun1 <- function(x, column){

   max(x[[column]])

 }

 fun1(df, "B")

[1] 11

Welcome to Intellipaat Community. Get your technical queries answered by top developers !


Categories

...