我想计算以下功能:
这里,g(x)是分布的密度函数。我想为几个发行版计算这个函数。另外,我使用库fitdistrplus。
要创建g,我使用do.call函数:
g<-function(x) {do.call(paste("d",i,sep=""),c(list(x=x),fti$estimate))}
fti $ estimate包含分布参数i。
G(x)是以这种方式计算的累积分布:
G<-function(x) {do.call(paste("p",i,sep=""),c(list(q=x),fti$estimate))}
我用这种方式计算f(x):
f<function(n,x) {n*g(x)*(1-G(x))^(n-1)
最后,我用这种方式计算h(x):
h<- function(n) {integrate(function(x) {x*f(n,x)},0,Inf)}
但是,我无法绘制这些函数,我收到以下错误:
1: In n*g(x):
Longer object length is not a multiple of shorter object length
2: In (1-G(x))^(n-1):
Longer object length is not a multiple of shorter object length
3: In x*f(n,x) :
Longer object length is not a multiple of shorter object length
此外,如果我想要绘制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()
}
答案 0 :(得分:3)
我不得不做一些逆向工程来找出你的 d1 , q1 等电话,但我认为你就是这样做的。也许最初的问题在于函数调用,如 f(n = 2:3,x = 1:9);在这样的调用中, n 应该是单个值,而不是值的向量。
即使 x 的长度是 n 长度的倍数,输出也很可能不是你真正想要的。 如果你试图给 n 一个矢量形式,你可能会得到一个循环(错误)输出:
> print(data.frame(n=2:3, x=1:6))
- n x
1 2 1
2 3 2
3 2 3
4 3 4
5 2 5
6 3 6
其中 x 将使用 n = 2 在 x = 1 , n = 3 处进行评估点 x = 2 等。你真正想要的是:
> 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 值调用来执行此操作:
lapply(2:3, FUN=function(n) (f(n, x=1:5)))
#[[1]]
#[1] 0.0004981910 0.0006066275 0.0007328627 0.0008786344 0.0010456478
#
#[[2]]
#[1] 0.0007464956 0.0009087272 0.0010974595 0.0013152213 0.0015644676
您是否对所有分配合适使用相同的 fti ,即使它应该有所不同?或 fti 中的 i 是否参考索引 i ,它是 ft [[i]]形式的拟合列表?
下面是一个包装函数,它为每个 n -value(以及发行版 i )单独调用:
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)
您在resultdist1n2 $ hres等中找到的所需 h 的结果:
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
编辑:以下是使用 lapply 函数调用 n 值 0&lt; = n&lt的每个向量的方法; = 256 :
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")
我会像这样分别绘制每个发行版 i 。
答案 1 :(得分:1)
问题是函数的plot
方法期望函数被矢量化。换句话说,如果给出长度为N的参数,它应该返回长度为N的结果向量。
您的minExpectedValue
不符合此要求;它期望n
将是一个标量,并返回一个标量。您可以使用Vectorize
快速解决此问题。您还需要指定要绘制的参数的名称,在本例中为n
。
minExpectedValue <- Vectorize(minExpectedValue)
plot(minExpectedValue, xname="n")