Comment concaténer des listes dans Rcpp
Je veux c()
2 listes dans Rcpp, mais j'ai du mal à obtenir la même structure que je le ferais dans R.
Voici quelques données simples + exemple:
rlist = list(a = "123")
listadd = list(typ = "fdb")
c(rlist, listadd)
ce qui me donne ceci:
$a [1] "123" $typ [1] "fdb"
Avec Rcpp, je n'ai trouvé push_back
qu'à faire plus ou moins ce que je voulais mais la structure est un peu différente. J'ai également essayé d'utiliser emplace_back
sur la base de cette référence mais cela ne semble pas être implémenté dans Rcpp.
cppFunction('
List cLists(List x, List y) {
x.push_back(y);
return(x);
}')
ce qui me donne:
cLists(rlist, listadd) $a [1] "123" [[2]] [[2]]$typ [1] "fdb"
Sur la base de cette question, je sais que je pourrais utiliser Language("c",x,y).eval();
la c()
fonction de R et obtenir le résultat correct, mais cela ne semble pas être la bonne manière.
Je me demandais donc comment concaténer correctement des listes dans Rcpp?
EDIT: Sur la base du commentaire de @ Dirk, j'ai essayé de créer une nouvelle liste et de les remplir avec les autres éléments de la liste, mais j'ai perdu les noms des éléments.
cppFunction('
List cLists(List x, List y) {
int nsize = x.size();
int msize = y.size();
List out(nsize + msize);
for(int i = 0; i < nsize; i++) {
out[i] = x[i];
}
for(int i = 0; i < msize; i++) {
out[nsize+i] = y[i];
}
return(out);
}')
Production:
cLists(rlist, listadd) [[1]] [1] "123" [[2]] [1] "fdb"
Les performances affectées pour votre implémentation semblent provenir de la copie de l' name
attribut dans des vecteurs de chaîne stl. Vous pouvez l'éviter comme ceci:
library(Rcpp)
library(microbenchmark)
cppFunction('
List cLists(List x, List y) {
int nsize = x.size();
int msize = y.size();
List out(nsize + msize);
CharacterVector xnames = x.names();
CharacterVector ynames = y.names();
CharacterVector outnames(nsize + msize);
out.attr("names") = outnames;
for(int i = 0; i < nsize; i++) {
out[i] = x[i];
outnames[i] = xnames[i];
}
for(int i = 0; i < msize; i++) {
out[nsize+i] = y[i];
outnames[nsize+i] = ynames[i];
}
return(out);
}')
x <- as.list(runif(1e6)); names(x) <- sample(letters, 1e6, T)
y <- as.list(runif(1e6)); names(y) <- sample(letters, 1e6, T)
microbenchmark(cLists(x,y), c(x,y), times=3)
Unit: milliseconds
expr min lq mean median uq max neval cld
cLists(x, y) 31.70104 31.86375 32.09983 32.02646 32.29922 32.57198 3 a
c(x, y) 47.31037 53.21409 56.41159 59.11781 60.96220 62.80660 3 b
Remarque: en copiant sur, std::string
vous perdez également d'éventuelles informations d'encodage de caractères, alors que travailler uniquement avec R / Rcpp préserve.