Reputation: 5
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)
Upvotes: 0
Views: 2283
Reputation: 1831
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
Upvotes: 0
Reputation: 160447
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
Upvotes: 1