R语言嵌套求和与乘积的优化函数编码报错求助
解决R中双重求和与乘积优化函数的"argument of length 0"错误
先直接点明你的错误根源:Error in 0:k : argument of length 0 是因为你在函数调用时传入了NA或者长度为0的k值,再加上代码里的索引错误、语法不匹配,导致整个逻辑崩溃。咱们一步步拆解修复:
1. 修正w函数的逻辑与语法隐患
你的w函数里有个明显的问题:choose(k, j * gam) 中,j是0到k的整数,若gam是实数,j*gam大概率不是整数,而choose()要求第二个参数必须是非负整数,这会直接报错。另外咱们把代码写得更健壮:
w <- function(n, k, gam) { # 强制k转为整数,避免传入非整数的情况 k_int <- as.integer(k) j <- 0:k_int # 这里我猜测你原本想写的是 choose(k, j) * gam^j(gam的j次方) # 原代码的j*gam作为choose的参数逻辑上不太通顺,如果你确实需要j*gam,得保证它是整数 terms <- choose(k_int, j) * gam^j w_val <- (1 / factorial(k_int)) * n * sum(terms) return(w_val) }
2. 彻底重构f函数解决核心错误
你的f函数有几个致命问题:
- R的向量索引是从1开始的!你定义
k = 0:10后,用i in 0:10取k[i],k[0]会返回NA,传入w函数后就会出现0:NA,直接触发argument of length 0错误 - 括号严重不匹配,导致代码逻辑根本无法正确执行
- 循环逻辑混乱,没有正确遍历x的所有元素计算乘积
重构后的f函数用sapply代替循环,更简洁且不易出错:
f <- function(gam, del) { x <- mydata # 确保mydata是全局环境中已定义的500元素向量 n <- 10 k_vals <- 0:10 # 重命名变量避免索引混淆 # 提前计算所有k对应的w值,避免重复计算提升效率 w_vals <- sapply(k_vals, function(k) w(n, k, gam)) # 遍历x的每个元素,计算对应项后求乘积 pdf_terms <- sapply(x, function(x_i) { # 对k从0到10求和,再计算每个x_i对应的项 sum(w_vals * (1/del + (n / x_i)^(n + 1))) }) pdf <- prod(pdf_terms) return(-pdf) # optim默认最小化,最大化L就是最小化-L }
3. 正确调用optim进行最大化
因为optim默认是最小化目标函数,而我们要最大化L(d,g),所以返回-pdf来实现等价转换。如果gam和del是正数(通常这类参数都是正的),可以用带约束的优化方法:
# 先确保mydata已经定义好 initial_params <- c(gam = 1, del = 1) # 设置合理的初始值 # 用L-BFGS-B方法,设置参数下限避免出现0或负数 optim_result <- optim( par = initial_params, fn = f, method = "L-BFGS-B", lower = c(0.001, 0.001) # 给参数设置极小的正下限 ) # 查看优化结果 print(optim_result)
几个关键注意事项
- 索引问题:永远记住R的向量/列表索引从1开始,别用0作为索引,否则会拿到NA
choose()的参数约束:choose(n, k)要求n和k都是非负整数,且k ≤ n,否则会返回NA或报错- 变量作用域:更规范的做法是把
mydata作为f函数的参数传入,而不是依赖全局变量,比如改成f <- function(gam, del, x = mydata) - 语法检查:写代码时注意括号匹配,RStudio的代码编辑器会有实时提示
内容的提问来源于stack exchange,提问作者fx7sts
相关产品推荐
相关产品推荐

