我正在尝试使用 Rcpp 进行一些重要性采样。一个关键的步骤是取重要性权重的平均值(在这个问题中)。我的程序同时对多个自变量进行重要性采样,因此代码使用矩阵而不是向量。下面是一个最小的可重现示例,它是应该发生的事情的理想化版本:
library(Rcpp)
cppFunction('
NumericVector test(){
NumericMatrix Numerator(100, 10);
NumericMatrix Denominator(100, 10);
for(int i = 0; i < 100; i++){
Numerator(i,_) = log(runif(10));
Denominator(i,_) = log(runif(10));
}
return colMeans(exp(Numerator - Denominator));
}
')
test()
Run Code Online (Sandbox Code Playgroud)
我收到这个我不明白的错误:
file17dd7b43bf04.cpp:16:10: error: no matching function for call to 'colMeans'
return colMeans(exp(Numerator - Denominator));
^~~~~~~~
/Library/Frameworks/R.framework/Versions/3.6/Resources/library/Rcpp/include/Rcpp/sugar/functions/rowSums.h:951:1: note: candidate template ignored: could not match 'MatrixBase' against 'Vectorized'
colMeans(const MatrixBase<RTYPE, NA, T>& x, bool na_rm = false) {
^
Run Code Online (Sandbox Code Playgroud)
从表面上看,编译器似乎试图告诉我它不知道函数colMeans是什么,但是 a) 我知道这至少包含在 Rcpp 1.0.3 及更高版本的语法糖中,并且 …
我的包中有一个Rcpp模块,它暴露了类,暴露了许多方法.是否可以使用roxygen2记录方法(在C++方面)?我的模块看起来像这样:
RCPP_MODULE(BayesFst) {
using namespace Rcpp;
class_<BayesFst>( "BayesFst")
.default_constructor("Standard constructor")
.method("printData", &BayesFst::printData)
.method("printCounts", &BayesFst::printCounts)
.method("printInitialPvals", &BayesFst::printInitialPvals)
.method("printFstSummary", &BayesFst::printFstSummary)
.method("run", &BayesFst::run)
.method("setData", &BayesFst::setData)
.method("setPriorParameters", &BayesFst::setPriorParameters)
.method("setRunParameters", &BayesFst::setRunParameters)
.method("ldiriTest", &BayesFst::ldiriTest)
.property("interaction", &BayesFst::getInteraction, &BayesFst::setInteraction)
;
Run Code Online (Sandbox Code Playgroud)
}
我想理想地记录所有这些方法.一个简单的想法是隐藏包装函数后面的类,然后从R包装器函数中调用方法,但这对我来说感觉有点不合适.
我已经尝试将roxygen注释行添加到函数中,但是因为它们没有以相同的方式导出,所以文档似乎没有被提取.
我有一个名为multicool的R包,它可以处理多集的排列。当前,在内部,存在一个C ++类,对initMC的调用将创建一个类Multicool的新对象,该对象可以完成我需要它执行的所有操作。但是,没有简单的方法来释放分配给该对象的内存。对于简单的使用来说并不重要,但是我有一个应用程序可能会调用数十万次。
我认为解决方案是使用Rcpp模块将类公开给R。但是,我尝试按照说明进行操作,但出现错误:
错误:找不到对象“ mcModule”
最初-我只想公开该对象及其构造函数。这是我的班级定义
#include <Rcpp.h>
using namespace Rcpp;
using namespace std;
class Multicool{
struct list_el {
int v;
struct list_el * n;
};
typedef struct list_el item;
item *h;
item *t;
item *i;
int *m_pnInitialState;
int *m_pnCurrState;
int m_nLength;
bool m_bFirst;
public:
// constructor
Multicool(IntegerVector x){
int nx = (int)x.size();
}
};
Run Code Online (Sandbox Code Playgroud)
然后我导出类和构造函数
RCPP_MODULE(mcModule){
using namespace Rcpp;
class_<Multicool>("Multicool")
.constructor<IntegerVector>()
;
}
Run Code Online (Sandbox Code Playgroud)
我加了线
import(Rcpp)
Run Code Online (Sandbox Code Playgroud)
到我的NAMESPACE文件
我已经添加了
RcppModules: mcModule
Run Code Online (Sandbox Code Playgroud)
到我的DESCRIPTION文件
并且我在.onLoad函数中添加了对loadRcppModules的调用
.onLoad <- function(libname, pkgname) {
loadRcppModules()
}
Run Code Online (Sandbox Code Playgroud)
所有这些都可以编译,并且程序包的构建没有任何抱怨。但是当我创建一个新的Multicool对象时,出现了上述错误 …
例如,我感兴趣的是用从每行中减去行最小值的列替换(几乎)所有data.frame列tibble。例如,如果X是一个数值矩阵,那么在基本 RI 中会写:
X = sweep(X, 1, apply(X, 1, min))
Run Code Online (Sandbox Code Playgroud)
我当前使用我拥有的数据执行此操作的函数(我将立即解释格式)将数字列拉出到矩阵中,进行扫描,然后cbind将转换后的数据和非数字数据再次组合在一起。那是:
subtractMin = function(data){
X = data %>%
select(starts_with("X")) %>%
as.matrix()
X = sweep(X, 1, apply(X, 1, min))
labels = data %>%
select(-starts_with("X"))
return(cbind(labels, X))
}
Run Code Online (Sandbox Code Playgroud)
我觉得这效率很低,必须有一种更聪明的方法。
我认为了解上下文并不重要,但我的数据有 77 行和 1133 列。其中四列包含标签信息,其余 1129 列包含每次观察的数值测量值(如果您关心的话,它们是光谱)。数值变量的数量如此之多,以至于单个mutate变量并不是前进的道路。同样 - 您仍然需要知道行最小值才能对每行进行标准化。
我被要求添加一些数据。原始数据有1000多列,所以我将提供一个较小的数据集
> x.df
nm X1799.38928 X1798.01526 X1796.64124 source color rep
1 s001c1 13901.944 13889.056 13883.334 01 c 1
2 s001c2 17293.586 17279.375 …Run Code Online (Sandbox Code Playgroud)