Rcpp:使用相等范围按键对多图值求和
Rcpp: sum multimap values by key using equal range
下面我有一个代码片段,它封装了我遇到的问题。
我想做的事情在 R 中是微不足道的,但在 Rcpp 中要困难得多。我只是根据各自的键尝试聚合值。在此示例中,我只是试图获取与第一个键对应的值的总和。我在 C++ 中做过一些非常相似的事情,但出于某种原因,Rcpp 端口给我带来了问题。
另外,请注意,所提供的代码仅代表我遇到的更大问题。所以我明白,试图单独在 Rcpp 中实现这个并不是很好地利用时间。
#include <Rcpp.h>
using namespace Rcpp;
using namespace std;
// [[Rcpp::export]]
int mmap(List x) {
std::multimap<int, int> out;
for(int i = 0; i < x.size(); ++i) {
int key_temp = as<List>(as<List>(x[i]))[0];
int value_temp = as<List>(as<List>(x[i]))[1];
out.insert(make_pair(key_temp, value_temp));
}
pair<multimap<int, int>::iterator, multimap<int, int>::iterator> range = out.equal_range(1);
int total = accumulate(range.first, range.second, 0);
return total;
}
/*
xList <- list()
xList[[1]] <- list()
xList[[1]][1] <- 1
xList[[1]][2] <- 1
xList[[2]] <- list()
xList[[2]][1] <- 1
xList[[2]][2] <- 2
xList[[3]] <- list()
xList[[3]][1] <- 2
xList[[3]][2] <- 2
xList[[4]] <- list()
xList[[4]][1] <- 1
xList[[4]][2] <- 2
mmap(xList)
*/
您收到的第一条错误消息具有指导意义:
/usr/include/c++/7/bits/stl_numeric.h:127:18: error: no match for ‘operator+’ (operand types are ‘int’ and ‘std::pair’)
编译器不知道如何将起始值(int
)与迭代器的新值(pair
表示键值对)相加。幸运的是 std::accumulate
接受一个可选参数,其中包含要应用的函数。使用 C++11 我们可以使用一个简单的 lambda 函数:
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::plugins(cpp11)]]
// [[Rcpp::export]]
int mmap(List x) {
std::multimap<int, int> out;
for(int i = 0; i < x.size(); ++i) {
int key_temp = as<List>(as<List>(x[i]))[0];
int value_temp = as<List>(as<List>(x[i]))[1];
out.insert(std::make_pair(key_temp, value_temp));
}
auto range = out.equal_range(1);
int total = std::accumulate(range.first, range.second, 0,
[](int a, std::pair<const int, int> b) { return a + b.second; });
return total;
}
/*** R
xList <- list()
xList[[1]] <- list()
xList[[1]][1] <- 1
xList[[1]][2] <- 1
xList[[2]] <- list()
xList[[2]][1] <- 1
xList[[2]][2] <- 2
xList[[3]] <- list()
xList[[3]][1] <- 2
xList[[3]][2] <- 2
xList[[4]] <- list()
xList[[4]][1] <- 1
xList[[4]][2] <- 2
mmap(xList)
*/
结果:
> mmap(xList)
[1] 5
下面我有一个代码片段,它封装了我遇到的问题。
我想做的事情在 R 中是微不足道的,但在 Rcpp 中要困难得多。我只是根据各自的键尝试聚合值。在此示例中,我只是试图获取与第一个键对应的值的总和。我在 C++ 中做过一些非常相似的事情,但出于某种原因,Rcpp 端口给我带来了问题。
另外,请注意,所提供的代码仅代表我遇到的更大问题。所以我明白,试图单独在 Rcpp 中实现这个并不是很好地利用时间。
#include <Rcpp.h>
using namespace Rcpp;
using namespace std;
// [[Rcpp::export]]
int mmap(List x) {
std::multimap<int, int> out;
for(int i = 0; i < x.size(); ++i) {
int key_temp = as<List>(as<List>(x[i]))[0];
int value_temp = as<List>(as<List>(x[i]))[1];
out.insert(make_pair(key_temp, value_temp));
}
pair<multimap<int, int>::iterator, multimap<int, int>::iterator> range = out.equal_range(1);
int total = accumulate(range.first, range.second, 0);
return total;
}
/*
xList <- list()
xList[[1]] <- list()
xList[[1]][1] <- 1
xList[[1]][2] <- 1
xList[[2]] <- list()
xList[[2]][1] <- 1
xList[[2]][2] <- 2
xList[[3]] <- list()
xList[[3]][1] <- 2
xList[[3]][2] <- 2
xList[[4]] <- list()
xList[[4]][1] <- 1
xList[[4]][2] <- 2
mmap(xList)
*/
您收到的第一条错误消息具有指导意义:
/usr/include/c++/7/bits/stl_numeric.h:127:18: error: no match for ‘operator+’ (operand types are ‘int’ and ‘std::pair’)
编译器不知道如何将起始值(int
)与迭代器的新值(pair
表示键值对)相加。幸运的是 std::accumulate
接受一个可选参数,其中包含要应用的函数。使用 C++11 我们可以使用一个简单的 lambda 函数:
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::plugins(cpp11)]]
// [[Rcpp::export]]
int mmap(List x) {
std::multimap<int, int> out;
for(int i = 0; i < x.size(); ++i) {
int key_temp = as<List>(as<List>(x[i]))[0];
int value_temp = as<List>(as<List>(x[i]))[1];
out.insert(std::make_pair(key_temp, value_temp));
}
auto range = out.equal_range(1);
int total = std::accumulate(range.first, range.second, 0,
[](int a, std::pair<const int, int> b) { return a + b.second; });
return total;
}
/*** R
xList <- list()
xList[[1]] <- list()
xList[[1]][1] <- 1
xList[[1]][2] <- 1
xList[[2]] <- list()
xList[[2]][1] <- 1
xList[[2]][2] <- 2
xList[[3]] <- list()
xList[[3]][1] <- 2
xList[[3]][2] <- 2
xList[[4]] <- list()
xList[[4]][1] <- 1
xList[[4]][2] <- 2
mmap(xList)
*/
结果:
> mmap(xList)
[1] 5