Rcpp::IntegerVector get_which(Rcpp::LogicalVector row) { int j = 0; for (int i = 0; i < row.length(); i++) if (row(i)) j++; Rcpp::IntegerVector ret(j); for (int i = 0, j = 0; i < row.length(); i++) if (row(i)) ret(j++) = i + 1; // R is 1-based return ret; }
// [[Rcpp::export]] Rcpp::List subsetCounts(Rcpp::IntegerVector counts, Rcpp::IntegerVector start, Rcpp::IntegerVector width, Rcpp::LogicalVector strand){ if (start.length() != width.length() || start.length() != strand.length()) Rcpp::stop("provided vectors have different lengths..."); int nr = start.length(); int len = counts.length(); int tot = 0; int* S = start.begin(); int* W = width.begin(); for (int i = 0; i < nr; ++i){ int s = S[i] - 1; int w = W[i]; if (s < 0) Rcpp::stop("negative start positions are invalid"); if (s + w > len) Rcpp::stop("range exceeds the lengths of the counts vector"); tot += w; } Rcpp::IntegerVector res(tot); Rcpp::IntegerVector nstart(nr); Rcpp::IntegerVector nend(nr); int* R = res.begin(); int* C = counts.begin(); int* ST = strand.begin(); int* NS = nstart.begin(); int* NE = nend.begin(); int currpos = 0; for (int i = 0; i < nr; ++i){ NS[i] = currpos + 1; int w = W[i]; if (ST[i]) std::copy(C + S[i]-1, C + S[i]-1 + w, R + currpos); else std::reverse_copy(C + S[i]-1, C + S[i]-1 + w, R + currpos); currpos += w; NE[i] = currpos; } return List::create(_("counts")=res, _("starts")=nstart, _("ends")=nend); }