如何将一个值从嵌套函数返回到R

时间:2017-07-28 09:06:06

标签: r function nested return

我一直在编写一个函数来根据几个条件返回基本统计信息。我的参数是一个数据框,几列到一组和一个参数来检查特定值为" TRUE或FALSE&#34 ;和另一个传递必须提取统计数据的论据,如均值,中位数,唯一值,SD,VAR

getstack1< -function(DSET,X轴,颜色,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)

        } 
        }
    }  

现在我的主要功能是&#34; getstack1&#34;,实际参数是getstack1(sbarr,&#34;工作类&#34;,&#34;性&#34;,&#34;年龄&# 34;,&#34; count&#34;,&#34; true&#34;)

if(distval ==&#34; true&#34;)然后验证Aggval,如果是count,执行内部函数countfunc并将值返回给main函数。我一直面临着将stackval3值从内部函数返回到main函数的困难。

我甚至尝试将该值指定为全局使用 stackval3&lt; -
assign(&#34; stackval3&#34;,&#34; stackval4&#34;,envir = .GlobalEnv) 然后我试着在外面调用函数并传递参数。

A = countfunc(DSET,X轴,颜色,GROUPBY)

返回(A)

但消极。如果你共享一些方法或代码来重新调整stackval3的值到main函数。

我使用简单的if else返回其他统计信息,因为需要唯一值,我选择了函数。 提前致谢

我的数据示例:

> 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")

3 个答案:

答案 0 :(得分:0)

玩具示例

f1<-function(a,b){
  if(a<10){
    f2<-function(a,b){
      c=a+b
      return(c) 
    }
    out<-f2(a,b)
    out
  }

}
    f(1,3)

在你的情况下

  library(plyr); library(dplyr)
  library(plyr)

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

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



  if(distval=="true"){

    if(Aggval =="count"){

      countfunc<-function(dset,Xaxis,Color,Groupby){

        stackval3 <-- ddply(dset, c(Xaxis,Color), .fun = function(xx){ Ln=length(unique(xx[,Groupby],na.rm=TRUE))})
        return(stackval3)

      }

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

PS如果你的if块不满意,你应该返回一个替代值

答案 1 :(得分:0)

使用countfunc后,您必须将其分配给某个对象以存储它返回的内容。您好像是在A中这样做了,但它被注释掉了。 创建对象后(例如A),您可以在getstack1函数中使用它的内容。

你可以做的是在调试时学习一些技巧。尝试在browser()函数中插入getstack1作为第一行。运行定义并使用此功能后,它将停在该行,您可以检查或创建任何您想要的对象。有关如何在?browser()模式下导航的详细信息,请参阅browser

在代码中:

# I usually call all the necessary packages beforehand, but that's just me.
library(plyr)
library(dplyr)

# in hopes of making things less confusing, let's confine this function to a global scope
# you can call it from anywhere
countfunc <- function(dset,Xaxis,Color,Groupby) {
  # no need to assign this to an object or explicitly use `return`, the last expression
  # will automatically be the result of `countfun` function
  ddply(dset, c(Xaxis,Color), .fun = function(xx) length(unique(xx[,Groupby],na.rm=TRUE)))
}

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

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

  if(distval == "true"){
    if(Aggval == "count"){
      A <- countfunc(dset,Xaxis,Color,Groupby)
    } 
  }

  # if distval and Aggval evaluated to desired values,
  # you can extract data from A from here on and use it
  # however you want - even returning it as the result
}  

答案 2 :(得分:0)

您的代码存在一些问题。首先,你在函数内部调用library,包括两次调用library(plyr),这不是一个好主意。在主要功能之外调用library。其次,您使嵌套函数countfunc的定义取决于两个if语句,没有理由这样做。您可以/应该在main函数的开头定义它并使调用依赖于if语句,代码会更清晰。第三,你可能根本不需要assign<<-,但这只是猜测,如果没有数据样本和预期输出,就无法确定。您的代码的(可能是非工作的)修订版将是:

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

您可以在上面的代码中激发自己,并发布数据示例和预期输出以获得更好的答案。