首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >哪里定义分布函数用于适配(适配)或适配(质量)?

哪里定义分布函数用于适配(适配)或适配(质量)?
EN

Stack Overflow用户
提问于 2014-07-24 13:12:16
回答 1查看 3.2K关注 0票数 5

我想定义我自己的分布函数,以便在R中使用fitdist或fitdistr函数,例如在fitdistrplus包中使用fitdist。我定义了一个名为sgamma的定制发行版,如下所示:

代码语言:javascript
复制
dsgamma<-function(x,shape){return(dgamma(x,shape,scale=1));}
qsgamma<-function(p,shape){return(qgamma(p,shape,scale=1));}
psgamma<-function(q,shape){return(pgamma(q,shape,scale=1));}
rsgamma<-function(n,shape){return(rgamma(n,shape,scale=1));}

我的问题是,我应该在哪里定义这些功能。

如果上面的定义和声明是在顶层环境中进行的,那么我可以使用这个分布函数调用fitdist。换句话说,具有以下内容的脚本test1.R将运行良好:

代码语言:javascript
复制
rm(list=ls())
require(fitdistrplus);
dsgamma<-function(x,shape){return(dgamma(x,shape,scale=1));}
qsgamma<-function(p,shape){return(qgamma(p,shape,scale=1));}
psgamma<-function(q,shape){return(pgamma(q,shape,scale=1));}
rsgamma<-function(n,shape){return(rgamma(n,shape,scale=1));}
x<-rgamma(100, shape=0.4, scale=1);
zfit<-fitdist(x, distr=dsgamma, start=list(shape=0.3));

现在,如果我将上面的代码包装在一个函数中,它就不能工作了。见下文test2.R:

代码语言:javascript
复制
rm(list=ls())
testfit<-function(x)
{
    require(fitdistrplus);
    dsgamma<-function(x,shape){return(dgamma(x,shape,scale=1));}
    qsgamma<-function(p,shape){return(qgamma(p,shape,scale=1));}
    psgamma<-function(q,shape){return(pgamma(q,shape,scale=1));}
    rsgamma<-function(n,shape){return(rgamma(n,shape,scale=1));}
    zfit<-fitdist(x, distr=dsgamma, start=list(shape=0.3));
    return(zfit);
}

x<-rgamma(100, shape=0.4, scale=1);
zfit<-testfit(x);

我得到了以下错误:

代码语言:javascript
复制
Error in fitdist(x, distr = dsgamma, start = list(shape = 0.3)) : 
  The  dsgamma  function must be defined

注意,如果我替换

代码语言:javascript
复制
zfit<-fitdist(x, distr=dsgamma, start=list(shape=0.3));

使用

代码语言:javascript
复制
zfit<-fitdist(x, distr="sgamma", start=list(shape=0.3));

我猜关键的问题是,fitdist在哪里查找由参数distr指定的函数。我非常感谢你的帮助。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-07-24 16:02:24

问得好。造成此错误的原因是,fitdistrplus包的作者使用exists()检查函数所需参数的变化。

以下是fitdistmledist函数代码的摘录。其中作者取给出的distr值,在定义了fitdistmledist的全局环境和环境中寻找合适的密度和概率函数。

代码语言:javascript
复制
if (!exists(ddistname,mode="function"))
    stop(paste("The ", ddistname, " function must be defined"))
pdistname <- paste("p", distname, sep = "")
if (!exists(pdistname,mode="function"))
    stop(paste("The ", pdistname, " function must be defined"))

这是“存在”工作原理的摘录:

此函数用于查看名称‘x’是否在指定的环境中绑定到它的值。如果“”为“TRUE”,并且在指定的环境中找不到“x”的值,则搜索环境的包围帧,直到遇到名称“x”为止。有关环境结构及其附件的详细信息,请参见“环境”和“R语言定义”手册。

要了解更多关于为什么存在的信息,请检查本文:http://adv-r.had.co.nz/Environments.html

从本质上说,fitdist和mledist没有在您创建的函数的环境中进行搜索,从而给出了dsgamma (以及您定义的其他函数)不存在的错误。

通过使用<<-而不是<-来定义testfit()中的函数,可以很容易地绕过这一点。这将在全局上定义您的子函数。

代码语言:javascript
复制
 > testfit<-function(x)
 +     {
 +             require(fitdistrplus);
 +                 dsgamma<<-function(x,shape){return(dgamma(x,shape,scale=1))}
 +                 qsgamma<<-function(p,shape){return(qgamma(p,shape,scale=1))}
 +                 psgamma<<-function(q,shape){return(pgamma(q,shape,scale=1))}
 +                 rsgamma<<-function(n,shape){return(rgamma(n,shape,scale=1))}
 +                 zfit<-function(x){return(fitdist(x,distr="sgamma" , start=list(shape=0.3)))};
 +                 return(zfit(x))
 +         }
!> testfit(x)
 Fitting of the distribution ' sgamma ' by maximum likelihood
 Parameters:
       estimate Std. Error
 shape 0.408349 0.03775797

通过将envir=parent.frame()添加到下面的存在检查中,您可以修改fitdist代码,以便在函数的环境中进行搜索,但我不建议这样做。

代码语言:javascript
复制
if (!exists(ddistname,mode="function",envir=parent.frame()))

但是,这仍然不能解决您的问题,因为fitdist调用了mledistmledist也有相同的问题。

代码语言:javascript
复制
 Error in mledist(data, distname, start, fix.arg, ...) (from #43) :
   The  dsgamma  function must be defined

要采用这种方法,您还必须修改mledist并告诉它在parent.frame of fitdistr中搜索。每次加载库时,都必须进行这些更改。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24934716

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档