首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场

rcpp综述
EN

Stack Overflow用户
提问于 2014-01-14 14:22:08
回答 2查看 1K关注 0票数 2

假设我有一个data.frame,如下所示:

代码语言:javascript
运行
复制
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 (表示速度),可以这样做:

代码语言:javascript
运行
复制
DT <- as.data.table(DF)
DT[, .N, by=strata2013]
   strata2013 N
1:          b 4
2:          a 6

现在,我想尝试在Rcpp中实现这一点,作为一个学习练习。我已经编写并试用了下面所示的代码,这些代码应该提供相同的输出,但是它却给了我一个错误。下面是代码:

代码语言:javascript
运行
复制
#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;
}

以下是错误消息:

代码语言:javascript
运行
复制
conversion from 'Rcpp::Vector<16>::Proxy {aka Rcpp::internal::string_proxy<16>}' 
to 'const size_t { aka const long long unsigned int}' is ambiguous

我做错了什么?非常感谢你的帮助。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 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>来包括它。

代码语言:javascript
运行
复制
#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]
)
*/

给我

代码语言:javascript
运行
复制
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函数,所以如果您想跳过学习体验,可以使用预焙解决方案

代码语言:javascript
运行
复制
#include <Rcpp.h>
using namespace Rcpp;  

// [[Rcpp::export]]
IntegerVector LengthStrata( DataFrame dataset ) {
  Rcpp::CharacterVector strata = dataset["strata2013"];
  return table(strata);
}

糖提高了Rcpp功能的速度:

代码语言:javascript
运行
复制
 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
票数 8
EN

Stack Overflow用户

发布于 2014-01-14 14:32:00

我不知道你想做什么。当strata是向量时

代码语言:javascript
运行
复制
     Rcpp::CharacterVector strata=df["strate2013"];

那我不知道是什么

代码语言:javascript
运行
复制
     strata(uniqueStrata(i)).size()

应该能做到的。也许你可以用文字(或用一些示例代码和数据在R中)描述你在这里要做的事情。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21115899

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档