2014-10-21 3 views
0

Я хотел бы получить доступ к значению второго уникального элемента в целочисленном векторе, используя Rcpp, но вместо этого получаю вектор нулей, равный по длине значению второго элемент в целочисленном векторе. Что я делаю не так?Я не понимаю этого поведения в Rcpp

require(Rcpp) 
cppFunction("NumericVector test(IntegerVector labelling1) { 
    IntegerVector lvls = unique(labelling1); 
    return(lvls[1]); 
}") 

    test(1:5) 
#[1] 0 0 
+0

Я думаю, что я просил его, чтобы вернуть NumericVector не ИНТ поэтому, когда он принуждает Int к Numeri c vector это результат. – orizon

+0

Звуки о праве. – Nard

ответ

2

Существует на самом деле отдельный вопрос здесь: вы пытаетесь построить NumericVector из int и Rcpp выполняет следующие действия:

  1. Целочисленное значение 2 возвращается вашей функцией,
  2. A NumericVector сконструирован как NumericVector(2); т.е. NumericVector с длиной 2.

Если то, что вы действительно хотите это IntegerVector, представляющее значение по этому индексу, вы должны написать:

IntegerVector test(IntegerVector labelling1) { 
    IntegerVector lvls = unique(labelling1); 
    return IntegerVector::create(lvls[1]); 
} 

Или вы могли бы также сделать, используя атрибуты Rcpp (который обрабатывает преобразование из int в IntegerVector автоматически для вас):

#include <Rcpp.h> 
using namespace Rcpp; 

// [[Rcpp::export]] 
int test(IntegerVector labelling1) { 
    IntegerVector lvls = unique(labelling1); 
    return lvls[1]; 
} 

/*** R 
test(1:5) 
*/ 
+0

Я очень новичок в C++ и Rcpp, но мне кажется, что почти никто не хотел бы, чтобы этот тип преобразования от '' int'' до '' NumericVector' - было бы разумным или практичным дать ошибку или предупреждение когда пользователь пытается это сделать? – orizon

1

сахара Подменю ожидает IntegerVector в качестве индекса (http://gallery.rcpp.org/articles/subsetting/). Если вы хотите, чтобы имитировать функцию R в unique вам потребуются некоторые дополнительные изменения:

cppFunction("IntegerVector test(IntegerVector labelling1, int i) { 
       // get sorted unique values 
       IntegerVector lvls = sort_unique(labelling1); 
       // get unique values in order of occurence 
       IntegerVector lvls1 = lvls[match(lvls, labelling1) - 1]; 
       return(lvls1[IntegerVector::create(i - 1)]);}") 

test(c(5:1, 1L), 2) 
#[1] 4 
+0

Очевидно, что есть более эффективные возможности для поиска второго уникального элемента. – Roland

+0

Спасибо. (Я согласен, что есть более эффективные способы поиска второго уникального элемента, но это был минимальный пример, который реплицировал мою проблему). – orizon

Смежные вопросы