简体   繁体   中英

(Optim) Error: (list) object cannot be coerced to type 'double'

In a larger optimization task, i'm stuck at a point where I need to input a list into optim . However, when within the list there is a vector, I get the error

(list) object cannot be coerced to type 'double'

Below there's an reproducible example and the error source is in the butter line. Splitting it into scalars makes the code work, but what I really want to is a list like init_param (with butter being a vector).

fun = function(param_list){

  x2 = param_list[["x2"]]
  bread = param_list[["bread"]]
  x3 = param_list[["x3"]]
  butter = param_list[["butter"]]

  sum(
    (bread - 3)^2, (x2-4)^2, (x3-125)^2, (butter[1])^2, (butter[2])^2
    )
}

init_param = list(x3 = -1, bread = 50, x2 = 120, butter = c(1,2))

optim(par = init_param, fn = fun)

The arguments for par need to be scalar, so your butter is throwing things off.

One way to remedy this is to break out the vector into scalars. (I am preserving your ultimate sum formula, though this remedy could easily change things in different ways to get the same result.)

fun = function(param_list){

  x2 = param_list[["x2"]]
  bread = param_list[["bread"]]
  x3 = param_list[["x3"]]
  butter = c(param_list[["butter1"]], param_list[["butter2"]])

  sum(
    (bread - 3)^2, (x2-4)^2, (x3-125)^2, (butter[1])^2, (butter[2])^2
    )
}
init_param = list(x3 = -1, bread = 50, x2 = 120, butter1 = 1, butter2 = 2)

optim(par = init_param, fn = fun)
# $par
#            x3         bread            x2       butter1       butter2 
# 124.995189738   2.998084514   3.997427390   0.004101379  -0.005390156 
# $value
# [1] 7.930112e-05
# $counts
# function gradient 
#      262       NA 
# $convergence
# [1] 0
# $message
# NULL

The optim function requires the input to be a simple vector. You can restructure your code using unlist to explicitly create the vector from what you have, and then adjust your function and surrounding code.

init_param = list(x3 = -1, bread = 50, x2 = 120, butter = c(1,2))
param_vector <- unlist(init_param)
param_vector
#>      x3   bread      x2 butter1 butter2 
#>      -1      50     120       1       2

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM