You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

R语言求解方程遇optimize函数报错:invalid function value排查

Hey there! Let's break down what's going wrong here and fix it step by step.

The Root Cause of Your Error

The "invalid function value in 'optimize'" error happens because optimize() expects your function f(x) to return a single scalar value (one number) every time it's called. But right now, your f(x) is calculating values for all 8016 rows of your data frame at once, returning a vector of 8016 numbers. The optimization function can't work with that—it needs a single value to evaluate how "good" the current x is.

The Fix: Process Rows One at a Time

Since each row in your data frame needs its own unique seuil value, you need to run the optimization individually for each row. Here's how to do that cleanly:

Step 1: Define a Row-Specific Function

First, create a function that takes a single row of your data, extracts the relevant variables, and runs the optimization for just that row. We'll also tweak the logic to prioritize finding the root (where your core expression equals 0) instead of minimizing the absolute value, since that's your actual goal:

find_seuil <- function(row) {
  # Pull variables from the current row
  sA1 <- row$shortA1
  mA1 <- row$middleA1
  tA1 <- row$timeA1
  ms1 <- row$minshort1
  mm1 <- row$minmiddle1
  sB1 <- row$shortB1
  mB1 <- row$middleB1
  tB1 <- row$timeB1
  
  # Define the core function we want to find the root of
  core_func <- function(x) {
    -(1 - sA1 - mA1) * (tA1)^(1 + x) - 
      sA1 * (tA1 + ms1)^(1 + x) - 
      mA1 * (tA1 + mm1)^(1 + x) + 
      (1 - sB1 - mB1) * (tB1)^(1 + x) + 
      sB1 * (tB1 + ms1)^(1 + x) + 
      mB1 * (tB1 + mm1)^(1 + x)
  }
  
  # First try uniroot (more efficient if we can confirm a root exists in the interval)
  # Check if the function crosses zero in a reasonable interval (adjust if needed)
  low_val <- core_func(-10)
  high_val <- core_func(10)
  
  if (sign(low_val) != sign(high_val)) {
    # Use uniroot since we know there's a root in this range
    result <- uniroot(core_func, interval = c(-10, 10), tol = 1e-4)
    return(result$root)
  } else {
    # Fall back to optimize to find the minimum absolute value
    opt_result <- optimize(function(x) abs(core_func(x)), 
                           interval = c(-10, 10), 
                           maximum = FALSE, 
                           tol = 1e-4)
    return(opt_result$minimum)
  }
}

Step 2: Apply the Function to Every Row

Now use apply() (base R) or pmap_dbl() (tidyverse) to run this function on each row of your data frame:

Base R Approach:
# Apply the function row-by-row (margin = 1 means "rows")
d$seuil <- apply(d, 1, find_seuil)
Tidyverse Approach (if you use purrr):
library(purrr)
# pmap_dbl passes each row's columns as arguments to find_seuil
d$seuil <- pmap_dbl(d, find_seuil)

Key Notes to Avoid Future Issues

  1. Shrink Your Interval: Your original interval c(-10000, 10000) is way too large—it can cause numerical overflow (e.g., (small_number)^(1 + 10000) becomes 0, (large_number)^(1 + 10000) becomes infinity). Start with a reasonable range like c(-10, 10) and adjust only if some rows don't find a solution there.
  2. Why uniroot is Better: Since you're looking for a solution where your expression equals 0, uniroot() is more efficient than minimizing the absolute value—if you can confirm the function crosses zero in your interval (which you said is guaranteed, so this should work for most rows).
  3. Vectorization Pitfalls: R loves vectorization, but optimization functions like optimize() and uniroot() are designed for scalar inputs/outputs. Always wrap them in a row-wise operation when working with data frames.

内容的提问来源于stack exchange,提问作者Timothée David

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:14:09