Rap*_*ter 3 c c++ r inline rcpp
有人可以让我开始我需要做什么来实现Rcpp中的unlockEnvironment下面的代码?
碰到这个职位,并根据与C语言代码试图温斯顿畅的解决方案在线.它有效,但我觉得我对内联或C/C++知之甚少(实际上没什么,都是真的知道我在做什么;-)
所以我认为这将是一个很好的机会,最终开始学习如何使用R作为C和C++的接口.而且我想我会跳上Rcpp火车这样做!
require("inline")
inc <- '
/* This is taken from envir.c in the R 2.15.1 source
https://github.com/SurajGupta/r-source/blob/master/src/main/envir.c
*/
#define FRAME_LOCK_MASK (1<<14)
#define FRAME_IS_LOCKED(e) (ENVFLAGS(e) & FRAME_LOCK_MASK)
#define UNLOCK_FRAME(e) SET_ENVFLAGS(e, ENVFLAGS(e) & (~ FRAME_LOCK_MASK))
'
src <- '
if (TYPEOF(env) == NILSXP)
error("use of NULL environment is defunct");
if (TYPEOF(env) != ENVSXP)
error("not an environment");
UNLOCK_FRAME(env);
// Return TRUE if unlocked; FALSE otherwise
SEXP result = PROTECT( Rf_allocVector(LGLSXP, 1) );
LOGICAL(result)[0] = FRAME_IS_LOCKED(env) == 0;
UNPROTECT(1);
return result;
'
unlockEnvironment <- inline::cfunction(
signature(env = "environment"),
includes = inc,
body = src
)
Run Code Online (Sandbox Code Playgroud)
旁注:当我在/R我的包项目目录中以某种方式组织它时,我遇到了Winston代码的错误:
在大多数情况下使用S4方法,我试图将Winston的代码分解为.unlockEnvironment()我放入文件的标准R函数/R/.unlockEnvironment.r
然后我会给我的S4方法unlockEnvironment()在/R/unlockEnvironment.r.env:environment然后签名的方法将简单地调用.unlockEnvironment(env = env).
设置这样的东西,我最终得到以下错误:
.Primitive(".Call")(,env)中的错误:作为符号地址传递的NULL值
如果我将代码放在/R/.unlockEnvironment.r相应方法的目录中/R/unlockEnvironment.r(因此每次unlockEnvironment()调用相应的方法时重新获取内联代码),一切都运行正常 - 但由于重复的重新获取,它的效率非常低.
所以我想这必须要么与C代码的编写方式有关,要么与使用内联时组织基于C的函数的方式有关?
听起来你的问题基本上等于'我该如何使用Rcpp::attributes'?我建议您查看Rcpp Gallery中的许多示例以了解更多信息.
主要思想:编写一些C++代码,将其放入.cpp文件,然后调用Rcpp::sourceCpp(<file>)加载它.对于这个特例:
#include <Rcpp.h>
using namespace Rcpp;
/* This is taken from envir.c in the R 2.15.1 source
https://github.com/SurajGupta/r-source/blob/master/src/main/envir.c
*/
#define FRAME_LOCK_MASK (1<<14)
#define FRAME_IS_LOCKED(e) (ENVFLAGS(e) & FRAME_LOCK_MASK)
#define UNLOCK_FRAME(e) SET_ENVFLAGS(e, ENVFLAGS(e) & (~ FRAME_LOCK_MASK))
// [[Rcpp::export]]
bool unlock_environment(Environment env) {
UNLOCK_FRAME(env);
return FRAME_IS_LOCKED(env) == 0;
}
/*** R
env <- new.env()
lockEnvironment(env)
try(env$a <- 1) ## error
unlock_environment(env)
env$a <- 1
*/
Run Code Online (Sandbox Code Playgroud)
调用Rcpp::sourceCpp()包含这些内容的文件可以让我:
> Rcpp::sourceCpp('~/scratch/unlock.cpp')
> env <- new.env()
> lockEnvironment(env)
> try(env$a <- 1) ## error
Error in env$a <- 1 : cannot add bindings to a locked environment
> unlock_environment(env)
[1] TRUE
> env$a <- 1 ## success!
Run Code Online (Sandbox Code Playgroud)
这里的主要小功能:
bool是C++ bool类型,并且Environment是包含环境的Rcpp类型.SEXP.您可能也喜欢Hadley的adv-r介绍.
| 归档时间: |
|
| 查看次数: |
600 次 |
| 最近记录: |