c++ - Rcpp: neat way to compare strings derived from an R data frame? -
having headaches in rcpp handling strings, have looked @ "how test rcpp::charactervector elements equality" situation bit more complex that.
to illustrate, suppose have 200-row data frame of names , marks, generated randomly:
df = data.frame(name = paste("person", sample(letters[1:10],200,rep=true),sep=""), mark = pmax(pmin(round(rnorm(200,60,15)),100),0), stringsasfactors=false) i found following inline code (using rcpp) correctly works out sum of marks rows person named first person given in data frame (i.e. df$name[1] in r, or equivalently name[0] in rcpp code):
library(inline) fastfunc_good1 <- cxxfunction( signature(dfin = "data.frame"), plugin = "rcpp", body = ' rcpp::dataframe df(dfin); rcpp::charactervector name = df["name"]; rcpp::integervector mark = df["mark"]; rcpp::charactervector targetname(1); rcpp::charactervector thisname(1); int n = name.length(); int tot = 0; targetname = name[0]; std::string s_targetname = as<std::string>(targetname); (int = 0; < n; i++) { thisname=name[i]; std::string s_thisname = as<std::string>(thisname); if (s_thisname == s_targetname) { tot = tot + mark[i]; } } return(rcpp::wrap(tot)); ') now, want simplify as possible, it's messy have define separate variable represent value in name[], coerce std::string, , comparison. there must way of simplifying notation looks more following (which should noted not work!)...
fastfunc_bad1 <- cxxfunction( signature(dfin = "data.frame"), plugin = "rcpp", body = ' rcpp::dataframe df(dfin); rcpp::charactervector name = df["name"]; rcpp::integervector mark = df["mark"]; int n = name.length(); int tot = 0; (int = 0; < n; i++) { if (name[i] == name[0]) { tot = tot + mark[i]; } } return(rcpp::wrap(tot)); ') ultimately goal of mini learning project me figure out how iterate through unique names in df$name, compute mark sum each one, , return (the unique names , corresponding sums) neat data frame. i've figured out of nuts , bolts of how build , return final data frame other examples - it's string stuff described above that's causing me headaches. many in advance pointers!
you can use rcpp::as convert r objects c++ containers. following works me.
fastfunc_good2 <- cxxfunction( signature(dfin = "data.frame"), plugin = "rcpp", body = ' rcpp::dataframe df(dfin); std::vector<std::string> name = rcpp::as<std::vector<std::string> >(df["name"]); std::vector<int> mark = rcpp::as<std::vector<int> >(df["mark"]); int n = name.size(); int tot = 0; (int = 0; < n; i++) { if (name[i] == name[0]) { tot = tot + mark[i]; } } return(rcpp::wrap(tot)); ') > fastfunc_good1(df) [1] 1040 > fastfunc_good2(df) [1] 1040
Comments
Post a Comment