Factor::Factor(SEXP fac) { Rcpp::RObject x = Rcpp::RObject(fac); SEXP classAttr = x.attr("class"); std::string className; if(classAttr != R_NilValue) className = Rcpp::as<std::string>(classAttr); if(className != "factor") throw std::range_error("Invalid SEXP in Factor constructor"); levelNames = Rcpp::as<std::vector<std::string> >(x.attr("levels")); int nObs = Rf_length(fac); observations.resize(nObs); int *ip = INTEGER(fac); for(int j=0; j < nObs; ++j) observations[j] = ip[j]-1; }
SEXP collapsedList(Rcpp::List ll) { if (ll.length() == 0) return R_NilValue; Rcpp::List::iterator it = ll.begin(); switch(TYPEOF(*it)) { case REALSXP: { Rcpp::NumericVector v(ll.begin(), ll.end()); Rcpp::RObject ro = ll[0]; if (ro.hasAttribute("class")) { Rcpp::CharacterVector cv = ro.attr("class"); if ((cv.size() == 1) && std::string(cv[0]) == "Date") { Rcpp::DateVector dv(v); return dv; } if ((cv.size() == 2) && std::string(cv[1]) == "POSIXt") { Rcpp::DatetimeVector dtv(v); return dtv; } } return v; break; // not reached ... } case INTSXP: { Rcpp::IntegerVector v(ll.begin(), ll.end()); return v; break; // not reached ... } case LGLSXP: { Rcpp::LogicalVector v(ll.begin(), ll.end()); return v; break; // not reached ... } case STRSXP: { // minor code smell that this is different :-/ int n = ll.size(); Rcpp::CharacterVector v(n); for (int i=0; i<n; i++) { std::string s = Rcpp::as<std::string>(ll[i]); v[i] = s; } return v; break; // not reached ... } } return ll; }
void graphConvert(SEXP graph_sexp, residualConnectivity::context::inputGraph& boostGraph, std::vector<residualConnectivity::context::vertexPosition>& vertexCoordinates) { Rcpp::RObject graph = Rcpp::as<Rcpp::RObject>(graph_sexp); std::string className = Rcpp::as<std::string>(graph.attr("class")); Rcpp::NumericMatrix vertexCoordinates_matrix; if(className == "igraph") { Rcpp::Environment igraphEnv("package:igraph"); Rcpp::Function isDirected = igraphEnv["is_directed"]; if(Rcpp::as<bool>(isDirected(graph))) { throw std::runtime_error("Input `graph' must be undirected"); } Rcpp::Function layoutAuto = igraphEnv["layout.auto"]; vertexCoordinates_matrix = layoutAuto(graph); igraphConvert(graph_sexp, boostGraph); } else if(className == "graphNEL" || className == "graphAM") { Rcpp::S4 graphS4 = Rcpp::as<Rcpp::S4>(graph); Rcpp::S4 renderInfo = Rcpp::as<Rcpp::S4>(graphS4.slot("renderInfo")); Rcpp::List nodes = Rcpp::as<Rcpp::List>(renderInfo.slot("nodes")); Rcpp::Function length("length"), cbind("cbind"); if(Rcpp::as<int>(length(nodes)) > 0) { vertexCoordinates_matrix = Rcpp::as<Rcpp::NumericMatrix>(cbind(nodes["nodeX"], nodes["nodeY"])); } if(className == "graphNEL") graphNELConvert(graph_sexp, boostGraph); else graphAMConvert(graph_sexp, boostGraph); } else { throw std::runtime_error("Input graph must have class \"igraph\", \"graphAM\" or \"graphNEL\""); } std::size_t nVertexCoordinates = vertexCoordinates_matrix.nrow(); vertexCoordinates.clear(); vertexCoordinates.reserve(nVertexCoordinates); for(std::size_t i = 0; i < nVertexCoordinates; i++) { vertexCoordinates.push_back(residualConnectivity::context::vertexPosition((residualConnectivity::context::vertexPosition::first_type)vertexCoordinates_matrix((int)i, 0), (residualConnectivity::context::vertexPosition::second_type)vertexCoordinates_matrix((int)i, 1))); } }