向旧 R 包添加新函数时找不到 Rcpp C++ 二进制对象

问题描述 投票:0回答:1

我正在 MacOS Sonoma 下运行最新的 R 和 Rcpp。 我正在尝试将新的函数调用 C++ 代码添加到一个非常旧的包 (Hmisc) 中,并使用 Rcpp::compileAttributes() 进行设置。 新的 R 函数对 C++ 二进制对象的 .Call() 会导致找不到对象。 这是我所拥有的:

  • DESCRIPTION
    :导入:Rcpp 和 LinkingTo:Rcpp
  • NAMESPACE
    :导出('pMedian')和useDynLib(Hmisc,.registration = TRUE,.fixes ='F_')
    • .fixes='F_' 处理包中旧的 Fortran 二进制对象
  • src/init.c
    :对旧 Fortran 例程的多次引用,与新 C++ 例程无关
  • src/RcppExports.cpp
    :(
    RcppExports.o
    也存在),内容:
// Generated by using Rcpp::compileAttributes() -> do not edit by hand
// Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393

#include <Rcpp.h>

using namespace Rcpp;

#ifdef RCPP_USE_GLOBAL_ROSTREAM
Rcpp::Rostream<true>&  Rcpp::Rcout = Rcpp::Rcpp_cout_get();
Rcpp::Rostream<false>& Rcpp::Rcerr = Rcpp::Rcpp_cerr_get();
#endif

// hlqest
double hlqest(NumericVector x);
RcppExport SEXP _Hmisc_hlqest(SEXP xSEXP) {
BEGIN_RCPP
    Rcpp::RObject rcpp_result_gen;
    Rcpp::RNGScope rcpp_rngScope_gen;
    Rcpp::traits::input_parameter< NumericVector >::type x(xSEXP);
    rcpp_result_gen = Rcpp::wrap(hlqest(x));
    return rcpp_result_gen;
END_RCPP
}
  • src/hlqest.cpp
    :拥有包括
    // [[Rcpp::export]]
    在内的所有推荐代码,并且
    hlqest
    函数在交互式会话中运行良好,其中使用
    .cpp
    加载
    Rcpp::sourceCpp
    代码。
    hlqest.o
    也在那里。
  • R/RcppExports.R
    :包含以下内容,并且生成的 R 函数可以交互地运行良好,如上所述
hlqest <- function(x) {
    .Call(`_Hmisc_hlqest`, x)
}
  • R/pMedian.r
    其中包含以下内容
#' Pseudomedian
#'
#' Uses fast C++ code from the `DescTools` package to compute the pseudomedian of a numeric vector.  The pseudomedian is the median of all possible midpoints of two different observations.  The C++ code is originally from Monahan and Moser.  The pseudomedian is also called the Hodges-Lehmann one-sample estimator.
#' @title pMedian
#' @param x a numeric vector
#' @param na.rm set to `TRUE` to exclude `NA`s before computing the pseudomedian
#'
#' @return a scalar numeric value
#' @export
#' @md
#' @seealso <https://dl.acm.org/doi/10.1145/1271.319414>, <https://www4.stat.ncsu.edu/~monahan/jul10>
#' @examples
#' x <- 1:5
#' pMedian(x)
#' # Compare with brute force calculation and with wilcox.test
#' median(outer(x, x, '+')) / 2
#' wilcox.test(x, conf.int=TRUE)

pMedian <- function(x, na.rm = FALSE) {
  if(na.rm) x <- x[! is.na(x)]
  n <- length(x)
  if(n == 0) return(NA_real_)
  if(n == 1) return(as.double(x))
  .Call(`_Hmisc_hlqest`, x)
}

构建二进制

Hmisc
包并加载该包后,我在运行
pMedian(1:5)
时收到以下错误:
Error in pMedian(1:5) : object '_Hmisc_hlqest' not found
。 如有任何帮助,我们将不胜感激。

rcpp
1个回答
0
投票

这个想法是将

// [[Rcpp::export]]
放在你的函数
hlquest
之上。

RcppExports.cpp
RcppExports.R
然后做的是确保您可以进行 R 可调用
hlquest(x)
—— 因为这比上面显示的表达式更容易/更简单,即

.Call(`_Hmisc_hlqest`, x)

还有一两点需要注意的是

NAMESPACE
有一条线

useDynLib("Hmisc", .registration=TRUE)

因为上面的

.Call
不传递字符串并且不引用包。

我还发现,添加到现有包是最难的,因为对于没有

src/init.c
的“新”包,相应的条目会在
RcppExports.cpp
中自动创建,但如果我记得正确,
compileAttributes()
调用就会小心并且不会修改现有的
init.c
。 所以它很挑剔——但是如果你点了所有的 i-s 并交叉了所有的 t-s,它应该可以工作。

© www.soinside.com 2019 - 2024. All rights reserved.