2012-10-04 14 views
11

Tengo una lista en R que x < -list (c (1,2,3), c (4,5), c (5,5), c (6)) Quiero ingresar la lista a Rcpp y devolverlos como un vector promedio, c (2, 4.5, 5, 6).Cómo manejar la lista en R a Rcpp

No estoy seguro de cómo manejar la lista en Rcpp. Recibí un mensaje de error, ¿alguien podría verificar mi código?

library(inline) 

fx = cxxfunction(signature(x='List'), body = 
' 
    Rcpp::List xlist(x); 
    int n = xlist.size(); 
    double res[n]; 

    for(int i=0; i<n; i++) { 
     Rcpp NumericVector y(xlist[i]); 
     int m=y.size(); 
     res[i]=0; 
     for(int j=0; j<m; j++){ 
      res[i]=res[i]+y[j] 
     } 
    } 

    return(wrap(res)); 
' 
, plugin='Rcpp') 

x<-list(c(1,2,3), c(4,5), c(5,5), c(6)) 
fx(x) 

Respuesta

21

Un par de pequeños errores aquí:

  1. Dos errores de sintaxis: se necesitan para Rcpp::NumericVectory, y que carecen de un punto y coma en el último bucle.
  2. Un malentendido de C++: necesita algo como std::vector<double> res(n); como n no se conoce en tiempo de compilación.
  3. Usted fue demasiado agresivo/optimista al crear instancias de sus vectores de la lista, lo hice en dos declaraciones.

Esta versión funciona:

R> fx <- cxxfunction(signature(x='List'), plugin='Rcpp', body = ' 
+  Rcpp::List xlist(x); 
+  int n = xlist.size(); 
+  std::vector<double> res(n); 
+         
+  for(int i=0; i<n; i++) {  
+   SEXP ll = xlist[i]; 
+   Rcpp::NumericVector y(ll); 
+   int m=y.size(); 
+   res[i]=0;   
+   for(int j=0; j<m; j++){  
+    res[i]=res[i]+y[j]; 
+   }  
+  } 
+  
+ return(Rcpp::wrap(res));  
+ ') 
R> x<-list(c(1,2,3), c(4,5), c(5,5), c(6)) 
R> fx(x) 
[1] 6 9 10 6  
R> 

Editar: Aquí es una versión que es un poco más idiomática:

fx <- cxxfunction(signature(x='List'), plugin='Rcpp', body = ' 
    Rcpp::List xlist(x); 
    int n = xlist.size(); 
    Rcpp::NumericVector res(n); 

    for(int i=0; i<n; i++) { 
     SEXP ll = xlist[i]; 
     Rcpp::NumericVector y(ll); 
     for(int j=0; j<y.size(); j++){ 
      res[i] += y[j]; 
     } 
    } 

    return(res); 
') 
+0

muchas gracias. – user1690124

+0

Es un placer y, por favor, siéntase libre de "aceptar" (haga clic en la marca de verificación) y "upvote" (haga clic en el triángulo hacia arriba) como es común en StackOverflow para las respuestas que se consideren adecuadas. –

+0

¿Entiendo correctamente que esta solución solo funciona para este nivel particular de listas de anidamiento? –