Here is a simple example of what I would like to do: Given a data frame foo with variables x and fn. Suppose fn is a vector of characters which correspond to names of previously defined functions which have only one argument. I would like a vector returned where fn is applied to x foo <- data.frame(x=c(2,5,7), fn = letters[c(6,7,6)]) foo$fn <- as.character(foo$fn) "f" <- function(x){17*x} "g" <- function(x){3*x} foo x fn 1 2 f 2 5 g 3 7 f wanted: a function which returns c(f(2),g(5),f(7)) = c(34, 15, 119) A simple application of do.call doesn't do what I need (it applies the function f to each x):> do.call(foo$fn,args=list(x = foo$x))[1] 34 85 119 Whereas the following works but seems like overkill.> diag(sapply(foo$fn,do.call,args=list(x=foo$x)))[1] 34 15 119 Another idea that didn't work: do.call("evalq",args =list(paste(foo$fn,"(foo$x)",sep=""))) [1] "f(foo$x)" "g(foo$x)" "f(foo$x)" Thanks in advance Anne ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Anne E. York National Marine Mammal Laboratory Seattle WA 98115-0070 USA e-mail: anne.york at noaa.gov Voice: +1 206-526-4039 Fax: +1 206-526-6615 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ripley@stats.ox.ac.uk
2002-Dec-16 20:19 UTC
[R] applying a different function to rows of a dataframe
Looks to me like you want sapply(1:nrow(foo), function(i) get(foo$fn[i])(foo$x[i])) or the equivalent for loop. On Mon, 16 Dec 2002, Anne York wrote:> Here is a simple example of what I would like to do: > > Given a data frame foo with variables x and fn. Suppose fn is a vector of > characters which correspond to names of previously defined functions > which have only one argument. I would like a vector returned where fn is > applied to x > > foo <- data.frame(x=c(2,5,7), fn = letters[c(6,7,6)]) > foo$fn <- as.character(foo$fn) > > "f" <- function(x){17*x} > "g" <- function(x){3*x} > > > foo > x fn > 1 2 f > 2 5 g > 3 7 f > > wanted: a function which returns c(f(2),g(5),f(7)) = c(34, 15, 119) > > A simple application of do.call doesn't do what I need (it applies the > function f to each x): > > > do.call(foo$fn,args=list(x = foo$x)) > [1] 34 85 119 > > Whereas the following works but seems like overkill. > > > diag(sapply(foo$fn,do.call,args=list(x=foo$x))) > [1] 34 15 119 > > Another idea that didn't work: > > do.call("evalq",args =list(paste(foo$fn,"(foo$x)",sep=""))) > [1] "f(foo$x)" "g(foo$x)" "f(foo$x)" > > Thanks in advance > Anne > > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > Anne E. York > National Marine Mammal Laboratory > Seattle WA 98115-0070 USA > e-mail: anne.york at noaa.gov > Voice: +1 206-526-4039 > Fax: +1 206-526-6615 > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > ______________________________________________ > R-help at stat.math.ethz.ch mailing list > http://www.stat.math.ethz.ch/mailman/listinfo/r-help >-- Brian D. Ripley, ripley at stats.ox.ac.uk Professor of Applied Statistics, http://www.stats.ox.ac.uk/~ripley/ University of Oxford, Tel: +44 1865 272861 (self) 1 South Parks Road, +44 1865 272860 (secr) Oxford OX1 3TG, UK Fax: +44 1865 272595