2017-04-22 188 views
0

我写了一个最大似然函数的简单函数,并希望此函数根据其参数的不同值使用for循环给出不同的结果。这就是我的函数包括基于for循环的表达式。我的功能运行良好,结果保存在列表中。然后,由于我有两个不同的结果,我想基于我的函数的每个部分将optim函数应用于我的函数。例如,在r中使用for循环应用最佳函数

ff <- function(x,mu=c(2,0.5),sd=c(0.2,0.3)){ 
    out <- vector("list",2) 
    for (i in 1:2){ 
    out[[i]] <- -sum(log(dnorm(x,mu[[i]],sd[[i]]))) ## here I have two different part of my funcitons wrap as one using for loop. 
    } 
return(out) 
} 


set.seed(123) 
    x <- rnorm(10,2,0.5) 
    x 

然后我的函数的结果是:

> ff(x) 
[[1]] 
[1] 25.33975 

[[2]] 
[1] 101.4637 

然后,因为我的功能有两个不同的部分包装成一个使用for循环,我想在Optim功能适用于这个函数基于它的每个部分。我尝试了很多自己的方法,但他们没有工作。这里是我的尝试之一:

op <- vector("list",2) 
for(i in 1:2){ 

op <- optim(c(0.5,0.5),fn=ff[[i]],i=i) 
} 

也就是说,我希望optim功能在我的论点i=1的第一价值评估我的功能,然后评估第二个i=2功能。

所以我funcitons没有包装如下:

ff_1 <- function(x,mu=c(2,0.5),sd=c(0.2,0.3)){ 
     -sum(log(dnorm(x,mu[[1]],sd[[1]]))) 

    return(out) 
    } 

ff_2 <- function(x,mu=c(2,0.5),sd=c(0.2,0.3)){ 
     -sum(log(dnorm(x,mu[[2]],sd[[2]]))) 

    return(out) 
    } 

,然后我需要使用两个不同的optim功能,每个功能。

我搜索了很多网站和R帮助网站,但我无法找到解决这个问题的方法。

请帮忙吗?

+0

我想我的问题是如何使' optim'函数自动移动我的功能'i'。 – Alice

+0

请问您可以使用'set.seed()'让您的输出可以被复制? – mtoto

+0

感谢@mtoto您的评论,我做到了。 – Alice

回答

2

试试这个,这是传递参数的Optim的就是这个样子,我想

# given data 
set.seed(123) 
x <- rnorm(10,2,0.5) 

# use vector parOpt instead of specifying two; for convience 
# with optim 
ff <- function(x, parOpt){ 
    out <- -sum(log(dnorm(x, parOpt[1], parOpt[2]))) 
    return(out) 
} 


# parameters in mu,sd vectors arranged in list 
params <- list(set1 = c(2, 0.2), set2 = c(0.5, 0.3)) 

# output list 
out <- list() 

for(i in 1:2){ 
    # pass params (mu and sd) to optim, function ff and the data 
    # note, since function ff has x argument, specify that in optim 
    out[[i]] <- optim(par = params[[i]], fn=ff ,x=x) 

} 

应该给这样的事情:

[[1]] 
[[1]]$par 
[1] 2.0372546 0.4523918 

[[1]]$value 
[1] 6.257931 

[[1]]$counts 
function gradient 
     55  NA 

[[1]]$convergence 
[1] 0 

[[1]]$message 
NULL 


[[2]] 
[[2]]$par 
[1] 2.037165 0.452433 

[[2]]$value 
[1] 6.257932 

[[2]]$counts 
function gradient 
     73  NA 

[[2]]$convergence 
[1] 0 

[[2]]$message 
NULL 

希望这有助于。

+2

你正在赞美@din。那就是我正在寻找的东西。五从我开始到你的答案。 – Alice

+0

我们可以保留第一个函数并设置参数:ff < - function(x,params list(set1 = c(2,0.2),set2 = c(0.5,0.3))){ff < - function (x,parOpt){<-sum(log(dnorm(x,parOpt [1],parOpt [2]))) return(out) }}。你觉得@din怎么样? – Alice

+0

我实际上无法想象如何使用函数内部的循环执行相同的操作。 – din

2

作为替代方案,可以使用fitdistrplus包的命令fitdist找到相同的解决方案:

library(fitdistrplus) 
set.seed(123) 
x <- rnorm(10,2,0.5) 
mu.start <- c(2,0.5) 
sd.start <- c(0.2,0.3) 
op <- vector("list",2) 
for(i in 1:2){ 
    op[[i]] <- fitdist(x,"norm", start=c(mu.start[i],sd.start[i])) 
} 
op 

结果是:

[[1]] 
Fitting of the distribution ' norm ' by maximum likelihood 
Parameters: 
    estimate Std. Error 
1 2.0372546 0.1430588 
2 0.4523918 0.1011464 

[[2]] 
Fitting of the distribution ' norm ' by maximum likelihood 
Parameters: 
    estimate Std. Error 
1 2.037165 0.1430719 
2 0.452433 0.1011694 
+0

非常感谢您的帮助。那么,'fitdist'只能用于最大可能性。 – Alice

+1

它看起来比使用'optim'更容易,但是,optim可以与其他方法一起使用,例如期望最大化算法。 – Alice