如何访问data.table未导出的froll函数实现自定义权重移动平均?
需求与问题:在data.table中实现带自定义权重的快速移动平均
我希望在data.table对象上运行支持自定义权重的移动平均。对比下来,frollmean的速度远快于frollapply,甚至比仅支持wilder=T/F、无法自定义权重的TTR::EMA还要快——具体性能对比见文末。
我尝试使用frollmean底层调用的未导出函数data.table:::froll,它要求第一个参数必须是函数的字符名称(frollmean使用的是"mean"),但遇到了一系列问题:
调用data.table:::froll的直接错误
传入自定义函数名时直接触发报错:
data.table:::froll('f.roll', x$c, 10) Error in data.table:::froll("f.roll", x$c, 10) : Internal error: invalid fun argument in rolling function, should have been caught before. please report to data.table issue tracker.
修改环境的尝试均失败
我尝试通过调整环境让自定义函数被froll识别,但所有尝试都未成功:
尝试修改data.table包环境
e.dt <- as.environment('package:data.table') e.dt$froll <- data.table:::froll Error in e.dt$froll <- data.table:::froll (from c.ta.R#287) : cannot add bindings to a locked environment
创建子环境并绑定froll
e.dt2 <- new.env(parent=e.dt) e.dt2$froll <- data.table:::froll e.dt2$froll('f.roll', top.., n, na.rm=T) Error in e.dt2$froll("f.roll", x$c, n, na.rm = T) : Internal error: invalid fun argument in rolling function, should have been caught before. please report to data.table issue tracker.
将自定义函数绑定到子环境
e.dt2$f.roll <- f.roll e.dt2$froll('f.roll', top.., n, na.rm=T) Error in e.dt2$froll("f.roll", top.., n, na.rm = T) : Internal error: invalid fun argument in rolling function, should have been caught before. please report to data.table issue tracker.
查看froll的底层实现
查看froll的定义,发现它核心调用了C函数CfrollfunR:
data.table:::froll function (fun, x, n, fill = NA, algo = c("fast", "exact"), align = c("right", "left", "center"), na.rm = FALSE, hasNA = NA, adaptive = FALSE) { stopifnot(!missing(fun), is.character(fun), length(fun) == 1L, !is.na(fun)) algo = match.arg(algo) align = match.arg(align) ans = .Call(CfrollfunR, fun, x, n, fill, algo, align, na.rm, hasNA, adaptive) ans } <bytecode: 0x0000000013738b40> <environment: namespace:data.table> data.table:::CfrollfunR $name [1] "CfrollfunR" $address <pointer: 0x000000001ef93e80> attr(,"class") [1] "RegisteredNativeSymbol" $dll DLL name: datatable Filename: C:/bin/cygwin/cygwin64/home/Adi/R/win-library/4.0/data.table/libs/x64/datatable.dll Dynamic lookup: FALSE $numParameters [1] -1 attr(,"class") [1] "CallRoutine" "NativeSymbolInfo"
异常现象:mean可行但自定义函数不行
传入"mean"时froll能正常运行:
tail(e.dt2$froll('mean', x$c, 10, na.rm=T)) [1] 43.506 43.148 42.855 42.548 42.331 42.200
但我用DLL Export Viewer检查data.table的DLL文件C:\bin\cygwin\cygwin64\home\Adi\R\win-library\4.0\data.table\libs\x64\datatable.dll时,并未找到名为mean的函数;同时data.table包的命名空间里也没有导出或未导出的mean函数:
data.table:::mean Error in get(name, envir = asNamespace(pkg), inherits = FALSE) : object 'mean' not found data.table::mean Error: 'mean' is not an exported object from 'namespace:data.table'
求可行的解决方案。
附:性能对比(microbenchmark结果)
## Unit: milliseconds ## expr min lq mean median uq max neval ## frollapply 131736.6469 131736.6469 131736.6469 131736.6469 131736.6469 131736.6469 1 ## EMA 262.9931 262.9931 262.9931 262.9931 262.9931 262.9931 1 ## frollmean 97.0388 97.0388 97.0388 97.0388 97.0388 97.0388 1
后续说明
由于froll无法解决我的问题,我正在寻找其他替代方案。
内容的提问来源于stack exchange,提问作者Adrian Chira
相关产品推荐
相关产品推荐

