2012-10-04 4 views
11

Ich habe eine Liste in R, die x < -list (c (1,2,3), c (4,5), c (5,5), c (6)). Ich möchte die Liste zu Rcpp eingeben und sie als einen durchschnittlichen Vektor, c (2, 4.5, 5, 6) zurückgeben.Wie man Liste in R zu Rcpp behandelt

Ich bin mir nicht sicher, wie man die Liste in Rcpp behandelt. Ich habe eine Fehlermeldung erhalten. Könnte jemand meinen Code überprüfen?

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) 

Antwort

21

Ein paar kleine Fehler in hier:

  1. Zwei Syntaxfehler: Sie müssen Rcpp::NumericVector für y und Ihnen fehlt ein Semikolon in der letzten Schleife.
  2. Ein Missverständnis von C++: Sie brauchen so etwas wie std::vector<double> res(n); als n ist zur Kompilierzeit nicht bekannt.
  3. Sie waren zu aggressiv/optimistisch bei der Instanziierung Ihrer Vektoren von der Liste, ich tat dies in zwei Aussagen.

Diese Version funktioniert:

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> 

Edit: Hier ist eine Version, die ein wenig mehr idiomatische ist:

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

danke so sehr. – user1690124

+0

Mein Vergnügen, und bitte zögern Sie nicht zu "akzeptieren" (klicken Sie auf ein Häkchen) und "upvote" (klicken Sie auf nach oben gerichtete Dreieck) wie üblich auf StackOverflow für Antworten als geeignet angesehen. –

+0

Verstehe ich es richtig, dass diese Lösung nur für diese bestimmte Ebene der Schachtelungslisten funktioniert? –