Last active
December 10, 2015 15:28
-
-
Save hadley/4454601 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Bin { | |
public: | |
virtual int operator() (double val) const =0; | |
}; | |
class BinFixed : public Bin { | |
double width_; | |
double origin_; | |
public: | |
BinFixed (double width, double origin = 0) { | |
width_ = width; | |
origin_ = origin; | |
} | |
int operator() (double val) const { | |
return (val - origin_) / width_; | |
} | |
}; | |
class BinBreaks : public Bin { | |
NumericVector breaks_; | |
NumericVector::iterator breaks_it_, breaks_end_; | |
public: | |
BinBreaks (NumericVector breaks) { | |
breaks_ = breaks; | |
breaks_it_ = breaks.begin(); | |
breaks_end_ = breaks.end(); | |
} | |
int operator() (double val) const { | |
NumericVector::iterator | |
bin_it = std::upper_bound(breaks_it_, breaks_end_, val); | |
return std::distance(breaks_it_, bin_it); | |
} | |
}; | |
std::vector<int> bin_bin(NumericVector x, const Bin& binner) { | |
int bin, nmissing = 0; | |
std::vector<int> out; | |
NumericVector::iterator x_it = x.begin(), x_end; | |
for(; x_it != x.end(); ++x_it) { | |
double val = *x_it; | |
if (ISNAN(val)) { | |
++nmissing; | |
} else { | |
bin = binner(val); | |
if (bin < 0) continue; | |
// Make sure there's enough space | |
if (bin >= out.size()) { | |
out.resize(bin + 1); | |
} | |
++out[bin]; | |
} | |
} | |
// Put missing values in the last position | |
out.push_back(nmissing); | |
return out; | |
} | |
// [[Rcpp::export]] | |
std::vector<int> bin_bin_fixed(NumericVector x, double width, double origin = 0) { | |
const Bin& binner = BinFixed(width, origin); | |
return bin_bin(x, binner); | |
} | |
// [[Rcpp::export]] | |
std::vector<int> bin_bin_breaks(NumericVector x, NumericVector breaks) { | |
const Bin& binner = BinBreaks(breaks); | |
return bin_bin(x, binner); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment