在R中,您可以使用as.X在向量类型之间进行强制,例如as.character(1)as.integer(1).然而,我不知道在RCPP中是否有一种本地的、优雅的方式来做同样的事情.

首先,C API确实有一个我试图使用的AS_CHARACTER宏,但RCPP似乎没有定义它的位置包括Rdefines.h:

> as_character = Rcpp::cppFunction("CharacterVector as_character(RObject x){ return AS_CHARACTER(x); }")
file113af2570bd06.cpp: In function ‘Rcpp::CharacterVector as_character(Rcpp::RObject)’:
file113af2570bd06.cpp:6:49: error: ‘AS_CHARACTER’ was not declared in this scope
    6 | CharacterVector as_character(RObject x){ return AS_CHARACTER(x); }
      |                                                 ^~~~~~~~~~~~
make: *** [/usr/lib/R/etc/Makeconf:178: file113af2570bd06.o] Error 1
g++ -std=gnu++14 -I"/usr/share/R/include" -DNDEBUG   -I"/home/migwell/R/x86_64-pc-linux-gnu-library/4.2/Rcpp/include" -I"/tmp/RtmppCAKV8/sourceCpp-x86_64-pc-linux-gnu-1.0.10"    -fpic  -g -O2 -ffile-prefix-map=/build/r-base-LhKvHL/r-base-4.2.3=. -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2  -c file113af2570bd06.cpp -o file113af2570bd06.o
Error in sourceCpp(code = code, env = env, rebuild = rebuild, cacheDir = cacheDir,  : 
  Error 1 occurred building shared library.

如果我try 使用CharacterVector,它也无法编译:

> as_character = Rcpp::cppFunction(
+ "CharacterVector as_character(RObject x){ return CharacterVector::create(x); }"
+ )
In file included from /home/migwell/R/x86_64-pc-linux-gnu-library/4.2/Rcpp/include/Rcpp/Vector.h:50,
                 from /home/migwell/R/x86_64-pc-linux-gnu-library/4.2/Rcpp/include/Rcpp.h:40,
                 from file113af65cda53c.cpp:1:
/home/migwell/R/x86_64-pc-linux-gnu-library/4.2/Rcpp/include/Rcpp/vector/converter.h: In instantiation of ‘static SEXPREC* Rcpp::internal::string_element_converter<RTYPE>::get(const T&) [with T = Rcpp::RObject_Impl<Rcpp::PreserveStorage>; int RTYPE = 16; SEXP = SEXPREC*]’:
/home/migwell/R/x86_64-pc-linux-gnu-library/4.2/Rcpp/include/Rcpp/generated/Vector__create.h:84:34:   required from ‘static Rcpp::Vector<RTYPE, StoragePolicy> Rcpp::Vector<RTYPE, StoragePolicy>::create__dispatch(Rcpp::traits::false_type, const T1&) [with T1 = Rcpp::RObject_Impl<Rcpp::PreserveStorage>; int RTYPE = 16; StoragePolicy = Rcpp::PreserveStorage; Rcpp::traits::false_type = Rcpp::traits::integral_constant<bool, false>]’
/home/migwell/R/x86_64-pc-linux-gnu-library/4.2/Rcpp/include/Rcpp/generated/Vector__create.h:71:26:   required from ‘static Rcpp::Vector<RTYPE, StoragePolicy> Rcpp::Vector<RTYPE, StoragePolicy>::create(const T1&) [with T1 = Rcpp::RObject_Impl<Rcpp::PreserveStorage>; int RTYPE = 16; StoragePolicy = Rcpp::PreserveStorage]’
file113af65cda53c.cpp:6:72:   required from here
/home/migwell/R/x86_64-pc-linux-gnu-library/4.2/Rcpp/include/Rcpp/vector/converter.h:49:37: error: no matching function for call to ‘std::__cxx11::basic_string<char>::basic_string(const Rcpp::RObject_Impl<Rcpp::PreserveStorage>&)’
   49 |                         std::string out(input) ;
      |   

另一方面,它确实允许Rf_coerceVector,但这似乎不是最好的方法,因为如果我使用STRSXPRf_函数,我对纯C语言有相当深的了解:

> as_character = Rcpp::cppFunction(
+ "CharacterVector as_character(RObject x){ return Rf_coerceVector(x, STRSXP); }"
+ )
> as_character(1)
[1] "1"

在RCPP中执行此操作的最自然/最简单的方法是什么?

我正在使用:

  • R 4.2.3
  • RCPP 1.0.10

推荐答案

如果您仔细查看这十个小插曲提供的现有RCPP文档,其中包括两个介绍性的小插曲,其中一个完全集中于您在这里询问的转换,那么您可以包含两个central助手函数wrap()以将任何选项返回给SEXP,以及as<T>()(作为模板函数)将froma SEXP转换为模板类型.

> cppFunction("CharacterVector cnvrt(NumericVector x) \  # indented for display
                   { return as<CharacterVector>(x); }")  # else really one line
> cnvrt(1.23)
[1] "1.23"
> 

发生并且令人困惑的事情是,编译器经常自动注入从SEXPSEXP的现有转换,但它有时会出错,或者与其他模板化的元编程代码冲突(遗憾的是,这很复杂).例如,重载return语句经常会让我们感到刺痛.

所以我有一些由来已久的规则:

  • 如果有疑问,将赋值分离出来(并相信编译器会重新优化)
  • 对于转换,可能首先显式地从源对象转到SEXP,然后从SEXP转到目标对象
  • 换句话说,"先让它行得通,然后再让它变得花哨".

R相关问答推荐

为什么stat_bin在R中的ggplot中显示错误的数字?

在ComplexHeatmap中,如何更改anno_barplot()标题的Angular ?

如何替换R中数据集列中的各种字符串

如何对数据集进行逆向工程?

Highcharter多次钻取不起作用,使用不同方法

为什么横向页面会导致officeverse中的页码/节头/页脚出现问题?

用相同方法得到不同函数的ROC最优截断值

在R中使用数据集名称

计算时间段的ECDF(R)

使用带有OR条件的grepl过滤字符串

如何通过匹配R中所有可能的组合来从宽到长旋转多个列?

我如何使用循环来编写冗余的Rmarkdown脚本?

仅当后续值与特定值匹配时,才在列中回填Nas

通过初始的shiny 应用更新部署的shiny 应用的数据和参数,其中部署的应用程序显示为URL

SHILINY中DT列的条件着色

如何将宽格式的患者信息数据高效地转换为患者计数的时间序列?

如何将图例文本添加到图例符号中

网络抓取NBA.com

如何使用list_rind在列表中保留已命名但不包含第0行的记录?

R:改进实现简单模型