假设我有一个data.frame,如下所示:
set.seed(45)
DF <- data.frame(x=1:10, strata2013=sample(letters[1:3], 10, TRUE))
x strata2013
1 1 b
2 2 a
3 3 a
4 4 b
5 5 b
6 6 a
7 7 a
8 8 b
9 9 a
10 10 a我想得到列strata2013中每个唯一值的计数,然后,使用data.table (表示速度),可以这样做:
DT <- as.data.table(DF)
DT[, .N, by=strata2013]
strata2013 N
1: b 4
2: a 6现在,我想尝试在Rcpp中实现这一点,作为一个学习练习。我已经编写并试用了下面所示的代码,这些代码应该提供相同的输出,但是它却给了我一个错误。下面是代码:
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
NumericVector LengthStrata (CharacterVector uniqueStrata, DataFrame dataset ) {
int n = uniqueStrata.size();
NumericVector Nh(n);
Rcpp::CharacterVector strata=dataset["strate2013"];
for (int i = 0; i < n; ++i) {
Nh[i]=strata(uniqueStrata(i)).size();
}
return Nh;
}以下是错误消息:
conversion from 'Rcpp::Vector<16>::Proxy {aka Rcpp::internal::string_proxy<16>}'
to 'const size_t { aka const long long unsigned int}' is ambiguous我做错了什么?非常感谢你的帮助。
发布于 2014-01-14 22:04:38
如果我正确理解,您希望strata( uniqueStrata(i) )会子集向量,类似于R的子集。不幸的是,情况并非如此;您必须执行“手动”的子设置。Rcpp还没有“泛型”子设置可供使用。
当涉及到使用Rcpp时,您确实希望在可能的情况下利用C++标准库。生成这些计数的事实上的C++方法是使用std::map (或者std::unordered_map,如果可以假定为C++11),并使用如下内容。我包括一个利息基准。
注意:unordered_map实际上可以从tr1获得,用于预C++11,因此可以使用#include <tr1/unordered_map>来包括它。
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
IntegerVector LengthStrata( DataFrame dataset ) {
Rcpp::CharacterVector strata = dataset["strata2013"];
int n = strata.size();
std::map<SEXP, int> counts;
for (int i = 0; i < n; ++i) {
++counts[ strata[i] ];
}
return wrap(counts);
}
/*** R
library(data.table)
library(microbenchmark)
set.seed(45)
DF <- data.frame(strata2013=sample(letters, 1E5, TRUE))
DT <- data.table(DF)
LengthStrata(DF)
DT[, .N, by=strata2013]
microbenchmark(
LengthStrata(DF),
DT[, .N, by=strata2013]
)
*/给我
Unit: milliseconds
expr min lq median uq max neval
LengthStrata(DF) 3.267131 3.831563 3.934992 4.101050 11.491939 100
DT[, .N, by = strata2013] 1.980896 2.360590 2.480884 2.687771 3.052583 100在这种情况下,Rcpp解决方案要慢一些,这可能是因为将R对象移动到和从C++容器中移动所花费的时间,但希望这是有指导意义的。
旁白:事实上,这已经包含在Rcpp中作为糖table函数,所以如果您想跳过学习体验,可以使用预焙解决方案
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
IntegerVector LengthStrata( DataFrame dataset ) {
Rcpp::CharacterVector strata = dataset["strata2013"];
return table(strata);
}糖提高了Rcpp功能的速度:
Unit: milliseconds
expr min lq median uq max neval
LengthStrata(DF) 5.548094 5.870184 6.014002 6.448235 6.922062 100
DT[, .N, by = strate2013] 6.526993 7.136290 7.462661 7.949543 81.233216 100发布于 2014-01-14 14:32:00
我不知道你想做什么。当strata是向量时
Rcpp::CharacterVector strata=df["strate2013"];那我不知道是什么
strata(uniqueStrata(i)).size()应该能做到的。也许你可以用文字(或用一些示例代码和数据在R中)描述你在这里要做的事情。
https://stackoverflow.com/questions/21115899
复制相似问题