在R中创建具有多个参数的函数

在R中创建具有多个参数的函数,r,function,plot,R,Function,Plot,我想计算以下函数: 这里,g(x)是分布的密度函数。我想对几个分布计算这个函数。此外,我使用FitDistripPlus库 要创建g,我使用函数do.call,方法如下: g<-function(x) {do.call(paste("d",i,sep=""),c(list(x=x),fti$estimate))} G<-function(x) {do.call(paste("p",i,sep=""),c(list(q=x),fti$estimate))} f<funct

我想计算以下函数:

这里,g(x)是分布的密度函数。我想对几个分布计算这个函数。此外,我使用FitDistripPlus库

要创建g,我使用函数do.call,方法如下:

g<-function(x) {do.call(paste("d",i,sep=""),c(list(x=x),fti$estimate))}
G<-function(x) {do.call(paste("p",i,sep=""),c(list(q=x),fti$estimate))}
f<function(n,x) {n*g(x)*(1-G(x))^(n-1)
h<- function(n) {integrate(function(x) {x*f(n,x)},0,Inf)}
除此之外,如果我只想绘制f(n,x),我会得到以下错误:

Error in list(x=x) :'x' is missing
我拥有的最小狙击集如下

#i can be "exp" "lnorm" "norm" etc...
for( i in functionsName) {
    png(paste(fileBase,"_",i,"_","graphics.png",sep=""))
    plot.new()

    fti<-fitdist(data, i)
    plotdist(data,i, para=as.list(fti[[1]]))
    #fti is a datatable or datafram
    #fti$estimate looks like this :
    # meanlog    sdlog 
    #8.475449 1.204958 

    #g
    pdf<-function(x) {do.call(paste("d",i,sep=""), c(list(x=x),fti$estimate))}  
#G
    cdf<-function(x) do.call(paste("p",i,sep=""), c(list(q=x),fti$estimate))


#f
    minLaw<- function(n,x) {n*pdf(x)*(1-cdf(x))^(n-1)}
    #h
    minExpectedValue<-function(n) {integrate(function(x) {x*minLaw(n,x)},0,Inf)}

    #these 2 following lines give an error
    plot(minExpectedValue)
    plot(minLaw)

    dev.off()
}
#我可以是“exp”“lnorm”“norm”等。。。
for(我在functionsName中){
png(粘贴(fileBase,“,”i,“,”graphics.png”,sep=”“))
plot.new()

fti我不得不做一些反向工程来计算d1、q1等调用,但我认为这就是你如何做的。也许最初的问题在于函数调用,比如f(n=2:3,x=1:9);在这样的调用中,n应该是一个值,而不是一个值向量

即使x的长度是n长度的倍数,输出也很可能不是您真正想要的。 如果您尝试给n一个向量形式,您可能会得到一个循环(假)输出:

其中,x在点x=1处用n=2计算,在点x=2处用n=3计算,等等。您真正想要的是:

> print(expand.grid(x=1:5, n=2:3))
-  x n
1  1 2
2  2 2
3  3 2
4  4 2
5  5 2
6  1 3
7  2 3
8  3 3
9  4 3
10 5 3
您可以分别为每个n值调用:

您是否对所有分布拟合使用了相同的fti,即使它本应不同?还是fti中的i指的是索引i,它是一个ft[[i]]形式的拟合列表

下面是一个包装函数,它分别为每个n值(和分布i)调用:


wrapper我不得不做一些反向工程来找出你的d1、q1等调用,但我认为这就是你如何做到的。也许最初的问题在于像f(n=2:3,x=1:9)这样的函数调用;在这样的调用中,n应该是一个值,而不是一个值向量

即使x的长度是n长度的倍数,输出也很可能不是您真正想要的。 如果您尝试给n一个向量形式,您可能会得到一个循环(假)输出:

其中,x在点x=1处用n=2计算,在点x=2处用n=3计算,等等。您真正想要的是:

> print(expand.grid(x=1:5, n=2:3))
-  x n
1  1 2
2  2 2
3  3 2
4  4 2
5  5 2
6  1 3
7  2 3
8  3 3
9  4 3
10 5 3
您可以分别为每个n值调用:

您是否对所有分布拟合使用了相同的fti,即使它本应不同?还是fti中的i指的是索引i,它是一个ft[[i]]形式的拟合列表

下面是一个包装函数,它分别为每个n值(和分布i)调用:


wrapper问题在于函数的
plot
方法期望函数将被向量化。换句话说,如果给定长度为N的参数,它应该返回长度为N的结果向量

您的
minExpectedValue
不满足此要求;它期望
n
将是一个标量,并返回一个标量。您可以使用
Vectorize
快速解决此问题。您还需要指定要绘制的参数的名称,在本例中为
n

minExpectedValue <- Vectorize(minExpectedValue)
plot(minExpectedValue, xname="n")

minExpectedValue问题在于函数的
plot
方法期望函数将被向量化。换句话说,如果给定长度为N的参数,它应该返回长度为N的结果向量

您的
minExpectedValue
不满足此要求;它期望
n
将是一个标量,并返回一个标量。您可以使用
Vectorize
快速解决此问题。您还需要指定要绘制的参数的名称,在本例中为
n

minExpectedValue <- Vectorize(minExpectedValue)
plot(minExpectedValue, xname="n")

minExpectedValue您正在运行的给出错误的确切代码行是什么?还有,
i
是什么,以及
fti
中的值是什么?您正在运行的给出错误的确切代码行是什么?还有,
i
是什么,以及
fti
中的值是什么?谢谢您的回答。我不知道您是否知道看到我的编辑,也许你会理解得更好。但是,我还是被卡住了。我的想法是为每0绘制h(n)。我的文章开始试图解释为什么你的h(n)不起作用-我是在您编辑时发布的。n和x都不能是向量,我认为您的代码隐式地包含了x值的向量。我现在编辑了我的答案,以便演示如何通过使用包装函数分别调用每个n值来测试多个n值。本质上,它做了许多调用:包装器(I=1,x=xs,n=nseq[1],fti=fti1);包装器(i=1,x=xs,n=nseq[2],fti=fti1),等等,其中nseq是n值为0:256的向量。对于每个分布,我将分别执行此操作,以便更改I和fti值。非常感谢!这次我了解了您的示例是如何工作的。但是,我得到以下错误:打开的设备太多。我现在不绘制任何内容,只需调用Lappy!我猜是绘图在后台执行ping并为每个n值打开一个新设备,或者您已经使用plot.new和png调用打开了图形设备,这些调用存在于您的代码中(由于没有您的数据,我只运行了我自己的独立示例)。尝试运行一些dev.off()关闭任何可能的png设备或重新启动会话。如果您的代码因错误而中断,则可能是因为有许多打开的设备从未因代码中断而关闭。我得到的另一个错误是:函数的计算结果是错误的长度调用:wrapper->minExpectedValue->integrate我使用下面的序列XS谢谢你的回答。我不知道你是否看到了我的编辑,也许你会更好地理解。但是,我仍然被卡住了。我的想法是每0绘制h(n)。我的帖子开始试图解释为什么你的h(n)不起作用-我是在您编辑时发布的。n和x都不能是向量,我认为您的代码隐式地包含了x值的向量。我现在编辑了我的答案,以便演示如何通过使用包装器函数分别调用每个n值来测试多个n值。本质上,它是在进行许多计算
wrapper <- function(i, x, n, fti){
    # As was provided by OP
    g<-function(x) {do.call(paste("d",i,sep=""),c(list(x=x),fti$estimate))}

    G<-function(x) {do.call(paste("p",i,sep=""),c(list(q=x),fti$estimate))}
    # does the i in fti refer to fit of i:th distribution, i.e. should it be a list where i:th location in ft is i:th distribution estimates?

    f<-function(n,x) {n*g(x)*(1-G(x))^(n-1)}
    # was missing a '-' and a '}'

    h<- function(n) {integrate(function(x) {x*f(n,x)},0,Inf)}

    list(gres = g(x), Gres = G(x), fres = f(n,x), hres = h(n))
}

# Example data
require("fitdistrplus")
data(groundbeef)
serving <- groundbeef$serving

# Gumbel distribution
d1 <- function(x, a, b) 1/b*exp((a-x)/b)*exp(-exp((a-x)/b))
p1 <- function(q, a, b) exp(-exp((a-q)/b))
q1 <- function(p, a, b) a-b*log(-log(p))

fti1 <- fitdist(serving, "1", start=list(a=10, b=10))
#> fti1$estimate
#       a        b 
#56.95893 29.07871

# Normal distribution

# dnorm, pnorm and qnorm are available in the default environment
d2 <- dnorm
p2 <- pnorm
q2 <- qnorm

fti2 <- fitdist(serving, "2", start=list(mean=0, sd=1))
#> fti2$estimate
#    mean       sd 
#73.67743 35.92581

# Sequence of x-values
xs <- seq(-100, 100, by=1)

print((resultdist1n2 <- wrapper(i=1, x=xs, n=2, fti=fti1))$hres)
print((resultdist1n3 <- wrapper(i=1, x=xs, n=3, fti=fti1))$hres)
print((resultdist2n2 <- wrapper(i=2, x=xs, n=2, fti=fti2))$hres)
print((resultdist2n3 <- wrapper(i=2, x=xs, n=3, fti=fti2))$hres)

plot(xs, resultdist1n2$fres, col=1, type="l", ylim=c(0,0.025), xlab="x", ylab="f(n, x)")
points(xs, resultdist1n3$fres, col=2, type="l")
points(xs, resultdist2n2$fres, col=3, type="l")
points(xs, resultdist2n3$fres, col=4, type="l")
legend("topleft", legend=c("Gamma (i=1) n=2", "Gamma (i=1) n=3", "Normal (i=2) n=2", "Normal (i=2) n=3"), col=1:4, lty=1)
h(n=2) for distribution i=1:
53.59385 with absolute error < 0.00022
h(n=3) for distribution i=1:
45.23146 with absolute error < 4.5e-05
h(n=2) for distribution i=2:
53.93748 with absolute error < 1.1e-05
h(n=3) for distribution i=2:
44.06331 with absolute error < 2e-05
ns <- 0:256
res1 <- lapply(ns, FUN=function(nseq) wrapper(i=1, x=xs, n=nseq, fti=fti1))
par(mfrow=c(1,2))
plot.new()
plot.window(xlim=c(-100,100), ylim=c(0, 0.05))
box(); axis(1); axis(2); title(xlab="x", ylab="f(n,x)", main="f(n,x) for gamma (i=1), n=0:256")
for(i in 1:length(ns)) points(xs, res1[[i]]$fres, col=rainbow(257)[i], type="l")
# perform similarly for the other distributions by calling with i=2, fti=fti2
# h as a function of n for dist i=1
plot(ns, unlist(lapply(res1, FUN=function(x) x$hres$value)), col=rainbow(257), xlab="n", ylab="h(n)", main="h(n) for gamma (i=1), n=0:256")
minExpectedValue <- Vectorize(minExpectedValue)
plot(minExpectedValue, xname="n")