I am trying to call a funtion within another function and I clearly am misunderstanding what I should do. Below is a simple example. I know lstfun works on its own but I cannot seem to figure out how to get it to work within ukn. Basically I need to create the variable "nts". I have probably missed something simple in the Intro or FAQ. Any help would be much appreciated. EXAMPLE ------------------------------------------------------------------------------- # create data.frame cata <- c( 1,1,6,1,1,4) catb <- c( 1,2,3,4,5,6) id <- c('a', 'b', 'b', 'a', 'a', 'b') dd1 <- data.frame(id, cata,catb) # function to create list from data.frame lstfun <- function(file, alpha , beta ) { cda <- subset(file, file[,1] == alpha) cdb <- subset (file, file[,1]== beta) list1 <- list(cda,cdb) } # funtion to operate on list ukn <- function(file, alpha, beta, nam1){ aa <- alpha bb <- beta myfile <- file nts <- lstfun(myfile, aa, bb) mysum <- nam1[,3]*5 return(mysum) } results <- ukn(dd1, "a", "b", nts$cda)
> -----Original Message----- > From: r-help-bounces at stat.math.ethz.ch > [mailto:r-help-bounces at stat.math.ethz.ch] On Behalf Of John Kane > Sent: Thursday, June 28, 2007 12:04 PM > To: R R-help > Subject: [R] Function call within a function. > > I am trying to call a funtion within another function > and I clearly am misunderstanding what I should do. > Below is a simple example. > I know lstfun works on its own but I cannot seem to > figure out how to get it to work within ukn. Basically > I need to create the variable "nts". I have probably > missed something simple in the Intro or FAQ. > > Any help would be much appreciated. > > EXAMPLE > -------------------------------------------------------------- > ----------------- > # create data.frame > cata <- c( 1,1,6,1,1,4) > catb <- c( 1,2,3,4,5,6) > id <- c('a', 'b', 'b', 'a', 'a', 'b') > dd1 <- data.frame(id, cata,catb) > > # function to create list from data.frame > lstfun <- function(file, alpha , beta ) { > cda <- subset(file, file[,1] == alpha) > cdb <- subset (file, file[,1]== beta) > list1 <- list(cda,cdb) > } > > # funtion to operate on list > ukn <- function(file, alpha, beta, nam1){ > aa <- alpha > bb <- beta > myfile <- file > nts <- lstfun(myfile, aa, bb) > mysum <- nam1[,3]*5 > return(mysum) > } > > results <- ukn(dd1, "a", "b", nts$cda)John, The first problem I see is one of scope. nts$cda refers to an object called nts which does not exist in the calling environment (it is local to the function ukn). So trying to call ukn() with nts results in an error. Second, even if you pass the name of the object, you will not be able to use it in ukn() in the manner that you are trying. Your ukn() function definition also requires that it know the inner workings of function lstfun(). Functions generally shouldn't require knowing how other functions work, they should only rely on what value is returned. You can get what you want by redefining ukn in the following way # funtion to operate on list ukn <- function(file, alpha, beta, nam1){ aa <- alpha bb <- beta myfile <- file nts <- lstfun(myfile, aa, bb) mysum <- nts[[nam1]][,3]*5 return(mysum) } And change the function call to results <- ukn(dd1, "a", "b", 1) This still leaves the functions coupled in a way that I don't like, but I'm not a good enough R programmer to solve that problem at the moment. Maybe someone else will come along with a better solution. Hope this is helpful, Dan Daniel J. Nordlund Research and Data Analysis Washington State Department of Social and Health Services Olympia, WA 98504-5204
The problem isn't the function call. First, list1 returned by lstfun does not name its elements so nts$cda won't work. See code change in lstfun. Second, specifying nts$cda as the nam1 argument tells R to look for the nts object in the environment in which ukn is called. However, the nts object is not created in the parent environment, it is created in the ukn's environment. Third, nam1[,3] should be nam1[2] as there is no third element to this list (although and this doesn't resolve the environment issue). I've modified your code below to work, but there are better ways to go about this. Thomas Lumley has a famous quote regarding parse. See http://tolstoy.newcastle.edu.au/R/e2/help/07/01/8059.html among others. I was once referred to Patrick Burns' S Poetry to learn about the "eval(parse(text=)))" paradigm which was very helpful. You may also want to brush up on environments (see ?environment) to learn more about lexical scoping. Hope this helps. -jason #MODIFIED CODE # create data.frame cata <- c( 1,1,6,1,1,4) catb <- c( 1,2,3,4,5,6) id <- c('a', 'b', 'b', 'a', 'a', 'b') dd1 <- data.frame(id, cata,catb) # function to create list from data.frame lstfun <- function(file, alpha , beta ) { cda <- subset(file, file[,1] == alpha) cdb <- subset (file, file[,1]== beta) ### CODE ADDED HERE list1 <- list(cda=cda,cdb=cdb) } # funtion to operate on list ukn <- function(file, alpha, beta, nam1){ aa <- alpha bb <- beta myfile <- file nts <- lstfun(myfile, aa, bb) ### CODE ADDED HERE mysum <- eval(parse(text=nam1)) #mysum <- nam1[,3]*5 return(mysum) } results <- ukn(dd1, "a", "b", "nts$cda") ### modified how called. ----- Original Message ----- From: "John Kane" <jrkrideau at yahoo.ca> To: "R R-help" <r-help at stat.math.ethz.ch> Sent: Thursday, June 28, 2007 12:03 PM Subject: [R] Function call within a function.>I am trying to call a funtion within another function > and I clearly am misunderstanding what I should do. > Below is a simple example. > I know lstfun works on its own but I cannot seem to > figure out how to get it to work within ukn. Basically > I need to create the variable "nts". I have probably > missed something simple in the Intro or FAQ. > > Any help would be much appreciated. > > EXAMPLE > ------------------------------------------------------------------------------- > # create data.frame > cata <- c( 1,1,6,1,1,4) > catb <- c( 1,2,3,4,5,6) > id <- c('a', 'b', 'b', 'a', 'a', 'b') > dd1 <- data.frame(id, cata,catb) > > # function to create list from data.frame > lstfun <- function(file, alpha , beta ) { > cda <- subset(file, file[,1] == alpha) > cdb <- subset (file, file[,1]== beta) > list1 <- list(cda,cdb) > } > > # funtion to operate on list > ukn <- function(file, alpha, beta, nam1){ > aa <- alpha > bb <- beta > myfile <- file > nts <- lstfun(myfile, aa, bb) > mysum <- nam1[,3]*5 > return(mysum) > } > > results <- ukn(dd1, "a", "b", nts$cda) > > ______________________________________________ > R-help at stat.math.ethz.ch mailing list > 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. >
Dear John, Perhaps I am mistaken in what you are trying to accomplish but it seems like what is required is that you call lstfun() outside of ukn(). [and remove the call to lstfun() in ukn()]. nts <- lstfun(myfile, aa, bb) results <- ukn(dd1, "a", "b", nts$cda) Alternatively, you can eliminate the fourth argument in ukn() and assign (via '<-') the results of lstfun() to 'nam1' within ukn() instead of saving to 'nts'... --- John Kane <jrkrideau at yahoo.ca> wrote:> I am trying to call a funtion within another function > and I clearly am misunderstanding what I should do. > Below is a simple example. > I know lstfun works on its own but I cannot seem to > figure out how to get it to work within ukn. Basically > I need to create the variable "nts". I have probably > missed something simple in the Intro or FAQ. > > Any help would be much appreciated. > > EXAMPLE >-------------------------------------------------------------------------------> # create data.frame > cata <- c( 1,1,6,1,1,4) > catb <- c( 1,2,3,4,5,6) > id <- c('a', 'b', 'b', 'a', 'a', 'b') > dd1 <- data.frame(id, cata,catb) > > # function to create list from data.frame > lstfun <- function(file, alpha , beta ) { > cda <- subset(file, file[,1] == alpha) > cdb <- subset (file, file[,1]== beta) > list1 <- list(cda,cdb) > } > > # funtion to operate on list > ukn <- function(file, alpha, beta, nam1){ > aa <- alpha > bb <- beta > myfile <- file > nts <- lstfun(myfile, aa, bb) > mysum <- nam1[,3]*5 > return(mysum) > } > > results <- ukn(dd1, "a", "b", nts$cda) > > ______________________________________________ > R-help at stat.math.ethz.ch mailing list > 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. >