2013-07-01 73 views
9

Tôi đang bối rối.Cách truy cập các phần tử của một vector trong Rcpp :: Danh sách

Sau đây biên dịch và hoạt động tốt:

#include <Rcpp.h> 
using namespace Rcpp; 
// [[Rcpp::export]] 
List test(){ 
    List l; 
    IntegerVector v(5, NA_INTEGER); 
    l.push_back(v); 
    return l; 
} 

Trong R:

R) test() 
[[1]] 
[1] NA NA NA NA NA 

Nhưng khi tôi cố gắng để thiết lập IntegerVector trong danh sách:

// [[Rcpp::export]] 
List test(){ 
    List l; 
    IntegerVector v(5, NA_INTEGER); 
    l.push_back(v); 
    l[0][1] = 1; 
    return l; 
} 

Nó không biên dịch:

test.cpp:121:8: error: invalid use of incomplete type 'struct SEXPREC' 
C:/PROGRA~1/R/R-30~1.0/include/Rinternals.h:393:16: error: forward declaration of 'struct SEXPREC' 

Trả lời

15

Đó là vì dòng này:

l[0][1] = 1; 

Trình biên dịch không có ý kiến ​​cho rằng l là danh sách các vectơ số nguyên. Về bản chất, l[0] cung cấp cho bạn SEXP (loại chung cho tất cả các đối tượng R) và SEXP là một con trỏ mờ đến SEXPREC trong đó chúng tôi không có quyền truy cập vào định nghĩa te (do đó mờ đục). Vì vậy, khi bạn thực hiện các [1], bạn cố gắng để có được SEXPREC thứ hai và do đó opacity làm cho nó không thể, và nó không phải là những gì bạn muốn anyway.

Bạn cần phải được cụ thể mà bạn đang giải nén một IntegerVector, vì vậy bạn có thể làm một cái gì đó như thế này:

as<IntegerVector>(l[0])[1] = 1; 

hoặc

v[1] = 1 ; 

hoặc

IntegerVector x = l[0] ; x[1] = 1 ; 

Tất cả những các tùy chọn hoạt động trên cùng một cấu trúc dữ liệu cơ bản.

Hoặc, nếu bạn thực sự muốn cú pháp l[0][1] bạn có thể xác định cấu trúc dữ liệu của riêng bạn thể hiện "danh sách các vectơ số nguyên". Đây là bản phác thảo:

template <class T> 
class ListOf { 
public: 

    ListOf(List data_) : data(data_){} 

    T operator[](int i){ 
     return as<T>(data[i]) ; 
    } 
    operator List(){ return data ; } 

private: 
    List data ; 
} ; 

Bạn có thể sử dụng cái nào, ví dụ: như thế này:

// [[Rcpp::export]] 
List test2(){ 
    ListOf<IntegerVector> l = List::create(IntegerVector(5, NA_INTEGER)) ; 
    l[0][1] = 1 ; 
    return l; 
} 

Cũng lưu ý rằng việc sử dụng .push_back trên Rcpp vectơ (bao gồm danh sách) yêu cầu một bản sao hoàn chỉnh của dữ liệu danh sách, có thể gây chậm bạn xuống. Chỉ sử dụng chức năng thay đổi kích thước khi bạn không có lựa chọn.

+1

Parfait! Cảm ơn bạn rất nhiều vì câu trả lời của bạn ! – statquant

+0

Một câu hỏi nữa Romain, tôi có thể tạo một 'Rcpp :: List' chứa' n' (nói 3) 'std :: vector ' hoặc 'Rcpp :: IntegerVector' với một lớp lót (có thể là một 'ctor'), như 'IntegerVector v (3, NA_INTEGER); Rcpp :: Danh sách kiểm tra (3, v) ' – statquant

+0

Điều này có ý định làm việc:' Danh sách l (3, IntegerVector (3, NA_INTEGER)) ', nhưng có lỗi đánh máy trong một tệp của chúng ta (' fill__dispatch' được viết là 'fill_dispatch' (một dấu gạch dưới)), do đó, nó không thành công. Tôi đã sửa nó cục bộ và sẽ cam kết sửa chữa đủ sớm. –

Các vấn đề liên quan