Search code examples
rfunctionnestedreturn

How to return a value from Nested function to main function in R


I have been writing a function to return the basic statistics based on few conditions.And my arguments are a data frame , few columns to group and 1 arguments to check a particular value for "TRUE or FALSE " and another argument to pass which statistics have to be extracted like Mean,median,unique values,SD,VAR

getstack1<-function(dset,Xaxis,Color,Groupby,Aggval,distval){

      dset<-na.omit(dset)
      Xaxis=dset[,Xaxis]
      Color=dset[,Color]
      Groupby=dset[,Groupby]


      library(plyr); library(dplyr)
      if(distval=="true"){

        if(Aggval =="count"){

          countfunc<-function(dset,Xaxis,Color,Groupby){
            library(plyr)
            stackval3 <-- ddply(dset, c(Xaxis,Color), .fun = function(xx){ Ln=length(unique(xx[,Groupby],na.rm=TRUE))})
            assign("stackval3", "stackval4", envir = .GlobalEnv)

          }

          # A=countfunc(dset,Xaxis,Color,Groupby)
          # return(A)

          return(stackval3)

        } 
        }
    }  

Now my main function is "getstack1", and the actual arguments are getstack1(sbarr,"workclass","sex","age","count","true")

if(distval=="true") then validating Aggval,If it is count, execute the inner function countfunc and return the value to main function. I have been facing difficulties to return the value stackval3 from inner to main function.

I even tried to assign the value as Global using stackval3 <--
assign("stackval3", "stackval4", envir = .GlobalEnv) then i tried to call the function outside and passing the arguments.

A=countfunc(dset,Xaxis,Color,Groupby)

return(A)

But negative. It would be if you share some methods or code to retune the value of stackval3 to main function.

I have return other statistics using a simple if else , I gone for function because of the need unique values. Thanks in advance

My data example :

> dput(head(sbarr,10))

structure(list(age = c(39L, 50L, 38L, 53L, 28L, 37L, 49L, 52L, 
31L, 42L), workclass = structure(c(8L, 7L, 5L, 5L, 5L, 5L, 5L, 
7L, 5L, 5L), .Label = c(" Federal-gov", " Local-gov", " NA", 
" Never-worked", " Private", " Self-emp-inc", " Self-emp-not-inc", 
" State-gov", " Without-pay"), class = "factor"), fnlwgt = c(77516L, 
83311L, 215646L, 234721L, 338409L, 284582L, 160187L, 209642L, 
45781L, 159449L), education = structure(c(10L, 10L, 12L, 2L, 
10L, 13L, 7L, 12L, 13L, 10L), .Label = c(" 10th", " 11th", " 12th", 
" 1st-4th", " 5th-6th", " 7th-8th", " 9th", " Assoc-acdm", " Assoc-voc", 
" Bachelors", " Doctorate", " HS-grad", " Masters", " Preschool", 
" Prof-school", " Some-college"), class = "factor"), education.num = c(13L, 
13L, 9L, 7L, 13L, 14L, 5L, 9L, 14L, 13L), marital.status = structure(c(5L, 
3L, 1L, 3L, 3L, 3L, 4L, 3L, 5L, 3L), .Label = c(" Divorced", 
" Married-AF-spouse", " Married-civ-spouse", " Married-spouse-absent", 
" Never-married", " Separated", " Widowed"), class = "factor"),  occupations = structure(c(1L, 4L, 6L, 6L, 11L, 4L, 9L, 4L, 
11L, 4L), .Label = c(" Adm-clerical", " Armed-Forces", " Craft-repair", 
" Exec-managerial", " Farming-fishing", " Handlers-cleaners", 
" Machine-op-inspct", " NA", " Other-service", " Priv-house-serv", 
" Prof-specialty", " Protective-serv", " Sales", " Tech-support", 
" Transport-moving"), class = "factor"), relationship = structure(c(2L, 
1L, 2L, 1L, 6L, 6L, 2L, 1L, 2L, 1L), .Label = c(" Husband", 
" Not-in-family", " Other-relative", " Own-child", " Unmarried", 
" Wife"), class = "factor"), race = structure(c(5L, 5L, 5L, 
3L, 3L, 5L, 3L, 5L, 5L, 5L), .Label = c(" Amer-Indian-Eskimo", 
" Asian-Pac-Islander", " Black", " Other", " White"), class = "factor"), 
sex = structure(c(2L, 2L, 2L, 2L, 1L, 1L, 1L, 2L, 1L, 2L), .Label = c(" Female", 
" Male"), class = "factor"), capital.gain = c(2174L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 14084L, 5178L), capital.loss = c(0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), hours.per.week = c(40L, 
13L, 40L, 40L, 40L, 40L, 16L, 45L, 50L, 40L), native.country = structure(c(40L, 
40L, 40L, 40L, 5L, 40L, 23L, 40L, 40L, 40L), .Label = c(" Cambodia", 
" Canada", " China", " Columbia", " Cuba", " Dominican-Republic", 
" Ecuador", " El-Salvador", " England", " France", " Germany", 
" Greece", " Guatemala", " Haiti", " Holand-Netherlands", 
" Honduras", " Hong", " Hungary", " India", " Iran", " Ireland", 
" Italy", " Jamaica", " Japan", " Laos", " Mexico", " NA", 
" Nicaragua", " Outlying-US(Guam-USVI-etc)", " Peru", " Philippines", 
" Poland", " Portugal", " Puerto-Rico", " Scotland", " South", 
" Taiwan", " Thailand", " Trinadad&Tobago", " United-States", 
" Vietnam", " Yugoslavia"), class = "factor"), income = structure(c(1L, 
1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L), .Label = c(" <=50K", 
" >50K"), class = "factor")), .Names = c("age", "workclass", 
"fnlwgt", "education", "education.num", "marital.status", "occupations", 
"relationship", "race", "sex", "capital.gain", "capital.loss", 
"hours.per.week", "native.country", "income"), row.names = c(NA, 
10L), class = "data.frame")

Solution

  • There are several problems with your code. First of all, you call library inside the function, including two calls to library(plyr), that's not a good idea. Call library outside the main function. Second, you make the definition of the nested function countfunc depend on two if statements, there's no reason to do that. You can/should define it at the beginning of the main function and make the calls to it depend on the if statements, the code would be much cleaner. Third, you probably don't need assign or <<- at all, but this is just a guess, without a dataexample and expected output, it's impossible to tell for sure. A (possibly non-working) revision of your code would be:

    library(plyr); library(dplyr)
    
    getstack1<-function(dset,Xaxis,Color,Groupby,Aggval,distval){
    
        countfunc<-function(dset,Xaxis,Color,Groupby){
            stackval3 <- ddply(dset, c(Xaxis,Color), .fun = summarize, Ln=length(unique(Groupby)))
            stackval3
        }
    
        dset<-na.omit(dset)
        stackval3 <- NULL
    
        if(distval=="true"){
            if(Aggval =="count"){
                stackval3 <- countfunc(dset,Xaxis,Color,Groupby)
            }
        }
        stackval3
    }
    
    getstack1(sbarr,"workclass","sex","age","count","true")
              workclass     sex Ln
    1           Private  Female  1
    2           Private    Male  1
    3  Self-emp-not-inc    Male  1
    4         State-gov    Male  1
    

    You can inspire yourself in the code above, and post a data example and expected output for a better answer.