2012-10-04 16 views
11

Mam listę w R, że x < -list (c (1,2,3), c (4,5), c (5,5), c (6)). Chcę wprowadzić listę do Rcpp i zwrócić je jako średni wektor, c (2, 4,5, 5, 6).Jak obsłużyć listę w R do Rcpp

Nie jestem pewien, jak obsługiwać listę w Rcpp. Dostałem komunikat o błędzie, więc czy ktoś mógłby sprawdzić mój kod?

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) 

Odpowiedz

21

Kilka drobnych błędów tu:

  1. Dwa błędy składniowe: trzeba Rcpp::NumericVector dla y i brakuje średnika w ostatniej pętli.
  2. Jedno nieporozumienie w C++: potrzebujesz czegoś takiego jak std::vector<double> res(n);, ponieważ n nie jest znane podczas kompilacji.
  3. Byliście zbyt agresywni/optymistyczni w tworzeniu swoich wektorów z listy, zrobiłem to w dwóch wypowiedziach.

Ta wersja działa:

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: Oto wersja, która jest trochę bardziej idiomatyczne:

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

bardzo dziękuję. – user1690124

+0

Cieszę się, że mogę "zaakceptować" (kliknij na znacznik wyboru) i "upvote" (kliknij na trójkąt skierowany do góry), co jest typowe dla StackOverflow w odpowiedziach uznawanych za odpowiednie. –

+0

Czy poprawnie rozumiem, że to rozwiązanie działa tylko dla tego konkretnego poziomu list zagnieżdżania? –