R语言fitWindowing传参异常:.Primitive("call")未求值promise问题
问题根因
这个问题是R语言默认的惰性求值机制导致的:函数传入的参数默认会封装为promise对象,只有第一次被使用时才会真正计算取值。你提到的wordLength(对应传入的weasel[["maxF"]])和symbolSet(对应传入的weasel[["symbolSet"]])两个参数只在调用fitTransformSupervised/fitTransform时才第一次被使用,此时promise的求值上下文发生变化,就会出现取值异常,你调试看到的unevaluated promise就是未求值的参数状态。
解决方案
1. 强制提前解析参数(最推荐)
在fitWindowing函数开头使用force()函数强制解析这两个参数,触发promise求值:
fitWindowing <- function(sfa, samples, windowSize, wordLength, symbolSet, normMean, lowerBounding) { # 新增以下两行强制参数求值 force(wordLength) force(symbolSet) # 原有代码保持不变 sfa[["transformation"]] <- createMFT(windowSize, normMean, lowerBounding) sa <- list() index = 0 for (i in 1:samples[["samples"]]) { newList <- getDisjointSequences(samples[["tseries"]][[i]], windowSize, normMean) for (j in 1:length(newList)) { index = index + 1 sa[[index]] <- newList[[j]] } } sa[["samples"]] <- index catch <- list() if (sfa[["SUP"]] == TRUE) catch <- fitTransformSupervised(sfa, sa, wordLength, symbolSet, normMean) else catch <- fitTransform(sfa, sa, wordLength, symbolSet, normMean) return(catch[[1]]) }
2. 调用函数前提前取出参数值
如果方案1无效,可以在调用fitWindowing的createWords函数中,先把对应值取出存为局部变量再传入,避免传递未求值的引用:
createWords <- function(weasel, samples, index, bar) { if (is.null(weasel[["signature"]][[index]])) { weasel[["signature"]][[index]] <- createSFA("INFORMATION_GAIN", TRUE, FALSE) # 提前取出参数值,完成求值 w_wordLength <- weasel[["maxF"]] w_symbolSet <- weasel[["symbolSet"]] weasel[["signature"]][[index]] <- fitWindowing( weasel[["signature"]][[index]], samples, weasel[["windowLengths"]][index], w_wordLength, w_symbolSet, weasel[["normMean"]], FALSE ) } # 剩余原有代码保持不变 wordsList <- list() catch <- list() for (i in 1:samples[["samples"]]) { catch <- SFAWindowingInt(weasel[["signature"]][[index]], samples[["tseries"]][[i]], weasel[["maxF"]]) weasel[["signature"]][[index]] <- catch[[1]] wordsList[[i]] <- catch[[2]] } weasel[["words"]][[index]] <- wordsList if (!is.null(bar)) { setTxtProgressBar(bar, index) } return(weasel) }
3. 检查函数定义加载状态
确保你修改后的fitWindowing函数已经被正确加载到R工作环境中,可以先执行rm(fitWindowing)删除旧的函数缓存,再重新source你的代码文件加载最新定义。
内容的提问来源于stack exchange,提问作者konogaame
相关产品推荐
相关产品推荐

