Rcpp: сумма значений мультикарты по ключу, используя равный диапазон - PullRequest
0 голосов
/ 24 июня 2018

Ниже у меня есть фрагмент кода, который содержит проблему, с которой я столкнулся.

То, что я пытаюсь сделать, было бы тривиально в 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)
 */

1 Ответ

0 голосов
/ 24 июня 2018

Поучительно одно из первых полученных вами сообщений об ошибках:

/ usr / include / c ++ / 7 / bits / stl_numeric.h: 127: 18: ошибка: нет совпадения для «operator +» (типы операндов: «int» и «std :: pair»)

Компилятор не знает, как добавить начальное значение (int) с новым значением от итератора (pair, представляющее пару ключ-значение). К счастью std::accumulate принимает необязательный аргумент с функцией, которая должна быть применена. Используя C ++ 11, мы можем использовать простую лямбда-функцию:

#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
...