gpt4 book ai didi

c - 在 C/C++ 中求值和替换

转载 作者:太空狗 更新时间:2023-10-29 15:00:42 25 4
gpt4 key购买 nike

我想在 C/C++ 中复制以下 R 函数:

fn1 = function(a, b) eval(a, b)

fn1(substitute(a*2), list(a = 1))
#[1] 2

我的前几次尝试导致错误(有时会崩溃),可能是因为我没有从列表对象中获取环境(我查看了 R 源代码,它使用了一堆内部在这一点上我认为我无法使用的功能),我认为这就是 Rf_eval 想要的,而不是对象本身。

require(Rcpp)
require(inline)

fn2 = cxxfunction(signature(x = "SEXP", y = "SEXP"),
'return Rf_eval(x, y);')

fn2(substitute(a*2), list(a = 1))
# error, object 'a' not found

另一种尝试是尝试调用 base R eval,这也给出了同样的错误:

require(Rcpp)
require(inline)

fn3 = cxxfunction(signature(x = "SEXP", y = "SEXP"),
'Function base_eval("eval"); return base_eval(x, y);',
plugin = 'Rcpp')

fn3(substitute(a*2), list(a = 1))
# again, object 'a' not found

每种方法都缺少什么,我怎样才能使它们都起作用?

最佳答案

在内部 Rf_eval 需要一个环境作为它的第二个参数。列表不是环境。您可以在 R 端使用 list2env 将列表转换为环境。因此,将此内容放在单独的 .cpp 文件中:

#include <Rcpp.h>
using namespace Rcpp ;

// [[Rcpp::export]]
SEXP fn_impl( Language call, List env){
return Rf_eval( call, env ) ;
}

sourceCpp 文件并创建包装器 R 函数以方便创建环境:

sourceCpp( "fn.cpp")
fn <- function(call, list){
fn_impl( call, list2env(list) )
}

fn(substitute(a*2), list(a = 1))

如果您不想创建环境,则需要多做一些工作,但您可以在 C++ 中导航调用并自行替换。我们在 dplyr 中做了很多这样的事情来实现混合评估。

对于 fn3,我认为这是关于 .Call 评估其参数。看看如果用这个函数替换 eval 会发生什么:

beval <- function(...){ print(match.call()); eval(...) }

这样你就可以看到这个函数是如何被调用的:

fn3 = cxxfunction(signature(x = "SEXP", y = "SEXP"),
'Function base_eval("beval"); return base_eval(x, y);',
plugin = 'Rcpp')

fn3(substitute(a*2), list(a = 1))
# (function (...)
# {
# print(match.call())
# eval(...)
# })(a * 2, list(a = 1))

您需要非标准评估。一种方法是发送未评估参数的列表。

dots <- function(...) {
eval(substitute(alist(...)))
}

fn <- function(...){
args <- dots(...)
fn_impl(args)
}

您在 C++ 层使用它来构造对 eval 的调用并对其求值:

#include <Rcpp.h>
using namespace Rcpp ;

// [[Rcpp::export]]
SEXP fn_impl( List args){
Language call = args[0] ;
List data = args[1] ;

// now construct the call to eval:
Language eval_call( "eval", call, data ) ;

// and evaluate it
return Rf_eval( eval_call, R_GlobalEnv ) ;
}

关于c - 在 C/C++ 中求值和替换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19729873/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com