假设,我有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
Run Code Online (Sandbox Code Playgroud)
我想获得的计数的每个唯一值列strata2013,然后,用data.table(速度),一个能做到这一点以这种方式:
DT <- as.data.table(DF)
DT[, .N, by=strata2013]
strata2013 N
1: b 4
2: a 6
Run Code Online (Sandbox Code Playgroud)
现在,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;
}
Run Code Online (Sandbox Code Playgroud)
这是错误消息:
conversion from 'Rcpp::Vector<16>::Proxy {aka Rcpp::internal::string_proxy<16>}'
to 'const size_t { aka const long long unsigned int}' is ambiguous
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?非常感谢您的帮助.
如果我理解正确,你希望strata( uniqueStrata(i) )将向量子集化,类似于R的子集操作.遗憾的是情况并非如此; 你必须"手动"执行子集化.Rcpp没有'通用'子集操作可用.
在使用时Rcpp,您确实希望尽可能利用C++标准库.产生这些计数的事实上的C++方式是使用a std::map(或者std::unordered_map,如果你可以假设C++ 11),使用类似下面的内容.我列出了兴趣基准.
来自Dirk的注释: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]
)
*/
Run Code Online (Sandbox Code Playgroud)
给我
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
Run Code Online (Sandbox Code Playgroud)
该Rcpp解决方案是在这种情况下可能更慢是由于它需要移动ř对象与C++的容器的时候,但希望这是有益的.
旁白:事实上,这已经Rcpp作为糖table功能包含在内,所以如果你想跳过学习经验,你可以使用预先制作的解决方案
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
IntegerVector LengthStrata( DataFrame dataset ) {
Rcpp::CharacterVector strata = dataset["strata2013"];
return table(strata);
}
Run Code Online (Sandbox Code Playgroud)
糖提高了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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
909 次 |
| 最近记录: |