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

优化场景下R语言出现Non-conformable arrays错误的排查求助

R语言nloptr::isres优化报错:数组维度不匹配

单独调用自定义滑动窗口计算函数fxn(3, 2350000)可正常返回0.67,但将该函数改造为适配nloptr包isres优化的fn函数后,运行优化代码时出现如下错误:

Error in income == 1 & truth == 0 : non-conformable arrays

完整代码

# 辅助函数与初始数据定义
somefunc <- function(values, weightvec) crossprod(values, weightvec)
tiny <- data.matrix(c(2293244, 2301521, 2318491, 2334855, 2350360, 2357444))
vec <- data.matrix(rep(1/3, 3))
roll <- data.matrix(unlist(lapply(seq(nrow(tiny) - 3 + 1), function(i) somefunc(tiny[i - 1 + seq(3), ], vec))))

zeros_ones <- data.matrix(c(0, 1, 1, 0, 0, 1))

deltat <- 3
truth <- data.matrix(zeros_ones[-1:-(deltat - 1), ])

# 可正常运行的函数
fxn <- function(deltat, thres) { 
    truth <- data.matrix(zeros_ones[-1:-(deltat - 1), ])
    income <- data.matrix(unlist(lapply(seq(nrow(tiny) - deltat + 1), function(i) somefunc(tiny[i - 1 + seq(deltat), ], data.matrix(rep(1/deltat, deltat))))))
    income[income < thres] <- 1
    income[income != 1] <- 0
    FP <- length(which(income == 1 & truth == 0))
    FN <- length(which(income == 0 & truth == 1))
    TP <- length(which(income == 1 & truth == 1))
    TN <- length(which(income == 0 & truth == 0))
    return(2 * (TP/(TP + FP)) * (TP/(TP + FN))/((TP/(TP + FP)) + (TP/(TP + FN))))
}

# 用于优化的函数(报错版本)
fn <- function(input) {
    deltat <- input[1]
    thres <- input[2]
    truth <- data.matrix(zeros_ones[-1:-(deltat - 1), ])
    income <- data.matrix(unlist(lapply(seq(nrow(tiny) - deltat + 1), function(i) somefunc(tiny[i - 1 + seq(deltat), ], data.matrix(rep(1/deltat, deltat))))))
    income[income < thres] <- 1
    income[income != 1] <- 0
    FP <- length(which(income == 1 & truth == 0))
    FN <- length(which(income == 0 & truth == 1))
    TP <- length(which(income == 1 & truth == 1))
    TN <- length(which(income == 0 & truth == 0))
    return(1 - ((2 * (TP/(TP + FP)) * (TP/(TP + FN)))/((TP/(TP + FP)) + (TP/(TP + FN)))))
}

x0 <- c(3, 2350000)
lb <- c(2, 2200000)
ub <- c(3, 2500000)

library(nloptr)    
isres(fn = fn, x0 = x0, lower = lb, upper = ub, maxeval = 100000)

错误原因

isres是全局优化算法,会在你设定的上下界内尝试浮点数类型的参数值,而不是仅整数。比如当deltat被传入2.1这类小数时:

  1. truth <- data.matrix(zeros_ones[-1:-(deltat - 1), ])中,deltat-1=1.1,-1:-(1.1)会被R处理为-1:-1,导致truth的长度为5;
  2. 而income的长度由seq(nrow(tiny)-deltat+1)生成,此时nrow(tiny)-deltat+1=6-2.1+1=4.9,seq(4.9)等价于seq(1,4),所以income长度为4;
  3. 两者长度不一致,执行income == 1 & truth == 0时就会触发维度不匹配错误。

而单独调用fxn(3,2350000)时,你传入的是整数3,所以truth和income长度都是4,不会报错。

解决方案

在fn函数中,将deltat强制转换为整数,确保参数符合滑动窗口的整数要求。可以根据需求选择取整方式(如四舍五入、向下取整),这里用四舍五入:

fn <- function(input) {
    deltat <- as.integer(round(input[1])) # 新增:强制转为整数
    thres <- input[2]
    truth <- data.matrix(zeros_ones[-1:-(deltat - 1), ])
    income <- data.matrix(unlist(lapply(seq(nrow(tiny) - deltat + 1), function(i) somefunc(tiny[i - 1 + seq(deltat), ], data.matrix(rep(1/deltat, deltat))))))
    income[income < thres] <- 1
    income[income != 1] <- 0
    FP <- length(which(income == 1 & truth == 0))
    FN <- length(which(income == 0 & truth == 1))
    TP <- length(which(income == 1 & truth == 1))
    TN <- length(which(income == 0 & truth == 0))
    return(1 - ((2 * (TP/(TP + FP)) * (TP/(TP + FN)))/((TP/(TP + FP)) + (TP/(TP + FN)))))
}

修改后重新运行isres优化代码,即可避免维度不匹配错误。

内容的提问来源于stack exchange,提问作者jlewis

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 22:29:53