2
votes

It seems possible to assign a vector of functions in R like this:

F <- c(function(){return(0)},function(){return(1)})

so that they can be invoked like this (for example): F[[1]]().

This gave me the impression I could do this:

DF <- data.frame(F=c(function(){return(0)}))

which results in the following error

Error in as.data.frame.default(x[[i]], optional = TRUE) : cannot coerce class ""function"" to a data.frame

Does this mean it is not possible to put functions into a data frame? Or am I doing something wrong?

2
Why you want to have function in data.frame? This is object that consists of vectors (numbers, characters) but not functions. Could you describe more precisely what you want to achieve?Maciej
@Maciej Functions are objects too, in an abstract sense. There are many possible reasons for wanting to treat them as data, which is why many languages allow it. In my case, the data frame holds a set of substitution macros associated with dynamically generated content. This allows a kind of document preprocessor to use the data frame to look up the function to call to generate the appropriate substitution.Museful

2 Answers

2
votes

No, you cannot directly put a function into a data-frame.

You can, however, define the functions beforehand and put their names in the data frame.

foo <- function(bar) { return( 2 + bar ) }
foo2 <- function(bar) { return( 2 * bar ) }
df <- data.frame(c('foo', 'foo2'), stringsAsFactors = FALSE)

Then use do.call() to use the functions:

do.call(df[1, 1], list(4))
# 6

do.call(df[2, 1], list(4))
# 8

EDIT

The above work around will work as long as you have a named function.

The issue seems to be that R see's the class of the object as a function, looks up the appropriate method for as.data.frame() (i.e. as.data.frame.function()) but can't find it. That causes a call to as.data.frame.default() which pretty must is a wrapper for a stop() call with the message you reported.

In short, they just seem not to have implemented it for that class.

1
votes

While you can't put a function or other object directly into a data.frame, you can make it work if you go via a matrix.

foo <- function() {print("qux")}
m <- matrix(c("bar", foo), nrow=1, ncol=2)
df <- data.frame(m)
df$X2[[1]]()

Yields:

[1] "qux"

And the contents of df look like:

  X1                                   X2
1 bar function () , {,     print("qux"), }

Quite why this works while the direct path does not, I don't know. I suspect that doing this in any production code would be a "bad thing".