I have a data frame with with several columns of parameters and one column of function name which should be used with these parameters. ?My goal is to call the appropriate function for each row and summarize the results in a list or data frame. ?I can partition the data frame according to function name, then call each function at a time. ?Is there a more elegant way to achieve this result with one call only? Below is an example. ?Here the functions are simple. ?It is possible to write a function that incorporates both ?the functions. ?It is not so easy in my actual task. ?My goal is to make one call and obtain res.df. Thanks, Naresh sum.sq <- function(x) {return(sum(x^2))} sum.cube <- function(x) {return(sum(x^3))} input.df <- data.frame(x1 = c(1,2,3,4), x2 = c(2,3,4,5), x3 = c(3,4,5,6), method = c(rep("sum.sq", 2), rep("sum.cube", 2)), case = c("a", "b", "c", "d")) library(plyr) res.df1 <- ddply(subset(input.df, method == "sum.sq"), c("case"), function(df) { x.vec <- c(df$x1, df$x2, df$x3) return(data.frame(sum.power = sum.sq(x.vec))) }) res.df2 <- ddply(subset(input.df, method == "sum.cube"), c("case"), function(df) { x.vec <- c(df$x1, df$x2, df$x3) return(data.frame(sum.power = sum.cube(x.vec))) }) res.df <- rbind(res.df1, res.df2) res.df <- merge(res.df, input.df[,c("method", "case")], by = "case")
1. return() is not needed in R functions (it's harmless, however). You might wish to go through an R function tutorial (many good ones are on the web) to learn about what slick things you can do with functions in R. 2. The following is just a brute force loop, so more elegant approaches are likely possible, but this seems to do what you want: sapply(seq_len(nrow(input.df)), function(i)do.call(input.df[i,4],list(x=unlist(input.df[i,1:3]))) ) ## see ?do.call 3. I suspect that a change in your data structure might facilitate your task, but of course, not knowing the task, I would not know what changes would be useful. See ?switch for something that might be related to what you are trying to do. Cheers, Bert Bert Gunter "The trouble with having an open mind is that people keep coming along and sticking things into it." -- Opus (aka Berkeley Breathed in his "Bloom County" comic strip ) On Sun, Mar 27, 2016 at 8:46 AM, Naresh Gurbuxani <naresh_gurbuxani at hotmail.com> wrote:> I have a data frame with with several columns of parameters and one column of function name which should be used with these parameters. My goal is to call the appropriate function for each row and summarize the results in a list or data frame. I can partition the data frame according to function name, then call each function at a time. Is there a more elegant way to achieve this result with one call only? > > Below is an example. Here the functions are simple. It is possible to write a function that incorporates both the functions. It is not so easy in my actual task. My goal is to make one call and obtain res.df. > > Thanks, > Naresh > > > > sum.sq <- function(x) {return(sum(x^2))} > > sum.cube <- function(x) {return(sum(x^3))} > > input.df <- data.frame(x1 = c(1,2,3,4), x2 = c(2,3,4,5), x3 = c(3,4,5,6), method = c(rep("sum.sq", 2), rep("sum.cube", 2)), case = c("a", "b", "c", "d")) > > library(plyr) > > res.df1 <- ddply(subset(input.df, method == "sum.sq"), c("case"), function(df) { > x.vec <- c(df$x1, df$x2, df$x3) > return(data.frame(sum.power = sum.sq(x.vec))) > }) > > res.df2 <- ddply(subset(input.df, method == "sum.cube"), c("case"), function(df) { > x.vec <- c(df$x1, df$x2, df$x3) > return(data.frame(sum.power = sum.cube(x.vec))) > }) > > res.df <- rbind(res.df1, res.df2) > res.df <- merge(res.df, input.df[,c("method", "case")], by = "case") > > > > > ______________________________________________ > R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code.
OOPS! I forgot to tell you that I first changed the "method" column, which is a factor, to character, with input.df$method <- as.character(input.df$method) Then things will work properly. -- Bert Bert Gunter "The trouble with having an open mind is that people keep coming along and sticking things into it." -- Opus (aka Berkeley Breathed in his "Bloom County" comic strip ) On Sun, Mar 27, 2016 at 11:35 AM, Bert Gunter <bgunter.4567 at gmail.com> wrote:> 1. return() is not needed in R functions (it's harmless, however). You > might wish to go through an R function tutorial (many good ones are on > the web) to learn about what slick things you can do with functions in > R. > > 2. The following is just a brute force loop, so more elegant > approaches are likely possible, but this seems to do what you want: > > sapply(seq_len(nrow(input.df)), > function(i)do.call(input.df[i,4],list(x=unlist(input.df[i,1:3]))) > ) > > ## see ?do.call > > 3. I suspect that a change in your data structure might facilitate > your task, but of course, not knowing the task, I would not know what > changes would be useful. See ?switch for something that might be > related to what you are trying to do. > > Cheers, > Bert > > > > > > Bert Gunter > > "The trouble with having an open mind is that people keep coming along > and sticking things into it." > -- Opus (aka Berkeley Breathed in his "Bloom County" comic strip ) > > > On Sun, Mar 27, 2016 at 8:46 AM, Naresh Gurbuxani > <naresh_gurbuxani at hotmail.com> wrote: >> I have a data frame with with several columns of parameters and one column of function name which should be used with these parameters. My goal is to call the appropriate function for each row and summarize the results in a list or data frame. I can partition the data frame according to function name, then call each function at a time. Is there a more elegant way to achieve this result with one call only? >> >> Below is an example. Here the functions are simple. It is possible to write a function that incorporates both the functions. It is not so easy in my actual task. My goal is to make one call and obtain res.df. >> >> Thanks, >> Naresh >> >> >> >> sum.sq <- function(x) {return(sum(x^2))} >> >> sum.cube <- function(x) {return(sum(x^3))} >> >> input.df <- data.frame(x1 = c(1,2,3,4), x2 = c(2,3,4,5), x3 = c(3,4,5,6), method = c(rep("sum.sq", 2), rep("sum.cube", 2)), case = c("a", "b", "c", "d")) >> >> library(plyr) >> >> res.df1 <- ddply(subset(input.df, method == "sum.sq"), c("case"), function(df) { >> x.vec <- c(df$x1, df$x2, df$x3) >> return(data.frame(sum.power = sum.sq(x.vec))) >> }) >> >> res.df2 <- ddply(subset(input.df, method == "sum.cube"), c("case"), function(df) { >> x.vec <- c(df$x1, df$x2, df$x3) >> return(data.frame(sum.power = sum.cube(x.vec))) >> }) >> >> res.df <- rbind(res.df1, res.df2) >> res.df <- merge(res.df, input.df[,c("method", "case")], by = "case") >> >> >> >> >> ______________________________________________ >> R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see >> https://stat.ethz.ch/mailman/listinfo/r-help >> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html >> and provide commented, minimal, self-contained, reproducible code.