r将值传递给内部函数找不到

时间:2013-04-03 21:12:01

标签: r

我还是R ......的新手并且读过以前类似的帖子......我认为这与r传递承诺但不是值的事实有关,但我不是很清楚错在哪里这里..

这是我想要尝试的代码的简单版本:

定义:

data<-data.frame(TYPE=as.integer(runif(20,1,3)),COL1=runif(20,1,100),COL2=runif(20,1,10))
RULEA=10
RULEB=20

我按以下方式运行:

f<-function(data,metric="A"){
  data<-ddply(data,.(TYPE),transform,SUMCOL1=sum(COL1,na.rm=TRUE),SUMCOL2=sum(COL2,na.rm=TRUE))
  data1<-f1(data=data,metric=metric)
  return(data1)
}

f1<-function(data=data,metric="A"){
  if(metric=="A"){
    RULE<-RULEA
    data$FACTOR<-data$COL1
  }else if(metric=="B"){
    RULE<-RULEB
    data$FACTOR<-data$COL1
  }
  if(nrow(data!=0)){
    x<-subset(data,FACTOR>1)
    if(nrow(x)!=0){
      x<-ddply(x,.(TYPE),mutate,sig=(max(FACTOR)>2*min(FACTOR)) & min(FACTOR) < RULE)
    }
  }

 return(x)
}

如果我运行如下:     F(数据,量度= “A”)

它会给我结果:

> f(data,metric="A")
Error in eval(expr, envir, enclos) : object 'RULE' not found

我不确定为什么它找不到“RULE”......? 谢谢你的帮助!

3 个答案:

答案 0 :(得分:2)

根据this(旧)讨论,这实际上是一个非常具有挑战性的问题。

正如该讨论所指出的那样,当您在mutate中评估自己的表达时,ddply已递交给已传递给ldply的{​​{1}} {1}}。现在llply必须弄清楚该表达式中的所有内容来自何处。看起来并不那么简单。

一种(可怕的)解决方法是更改​​mutate使用RULE的作业。哈德利在讨论中提到写一个明确的功能,这可能是一个更安全的选择。

答案 1 :(得分:2)

也许我在这里遗漏了一些内容,但如果RULE成为data.frame x的一部分,我们会对f1<-function(data=data,metric="A"){ if(metric=="A"){ # RULE<-RULEA data$RULE<-RULEA data$FACTOR<-data$COL1 }else if(metric=="B"){ # RULE<-RULEB data$RULE<-RULEB data$FACTOR<-data$COL1 } if(nrow(data!=0)){ x<-subset(data,FACTOR>1) if(nrow(x)!=0){ x<-ddply(x,.(TYPE),mutate,sig=(max(FACTOR)>2*min(FACTOR)) & min(FACTOR) < RULE) } } return(x) } f(data,metric="A") # TYPE COL1 COL2 SUMCOL1 SUMCOL2 RULE FACTOR sig # 1 1 43.983597 9.457873 496.6858 60.05813 10 43.983597 TRUE # 2 1 60.438590 4.196161 496.6858 60.05813 10 60.438590 TRUE # 3 1 20.251421 6.780956 496.6858 60.05813 10 20.251421 TRUE 进行评估:

f

我是基地的粉丝,所以我可能会像这样重写你的函数f1f<-function(data=data,metric='A'){ b<-by(data,data$TYPE, function(x) data.frame(max=max(x$COL1),min=min(x$COL1),SUMCOL1=sum(x$COL1),SUMCOL2=sum(x$COL2))) m<-do.call(rbind,b) m$TYPE<-rownames(m) m$sig<-m$max>(2*m$min) & m$min < switch(metric,A=RULEA,B=RULEB) merge(data,m)[,c(names(data),'SUMCOL1','SUMCOL2','sig')] } f(data,metric='A')

{{1}}

答案 2 :(得分:2)

使用data.table的方法可能很有用,因为它避免了这个问题。

请注意,我明确地复制每个函数中的data.tables,以使函数更像是一个常规的R函数 - 因此我并没有真正利用data.table内存效率,而是评估它的方式{{ 1}}很好(它会比j更快。)

一般来说,会有更多的ddply方式来做你想做的事情,而这个答案并不是真的那样。

data.table