3#include <RcppArmadillo.h>
14#include <unordered_set>
26static void erase_all(
string& input,
const string& pattern)
31 string::size_type position = 0;
33 while ((position = input.find(pattern, position)) !=
35 input.erase(position, pattern.size());
39static string erase_all_copy(
string input,
40 const string& pattern)
42 erase_all(input, pattern);
49static vector<string> split_any_of(
51 const string& delimiters,
52 bool compress =
false)
54 vector<string> output;
55 string::size_type begin = 0;
58 const auto separator = input.find_first_of(delimiters, begin);
60 if (separator == string::npos) {
61 output.emplace_back(input.substr(begin));
65 output.emplace_back(input.substr(begin, separator - begin));
68 begin = separator + 1;
72 begin = input.find_first_not_of(delimiters, separator);
75 if (begin == string::npos) {
76 output.emplace_back();
90static vector<double> GP_to_dosage(
const vector<T> &v,
const bool &missingToMean) {
91 vector<double> res( v.size() / 3.0);
95 int runningSum = 0, nValid = 0;
100 for(
int i=0; i<res.size(); i++){
102 value = v[3*i]*0 + v[3*i+1]*1 + v[3*i+2]*2;
107 value = std::numeric_limits<double>::quiet_NaN();
108 missing.push_back(i);
120 double mu = runningSum / (double) nValid;
125 for(
const int& i : missing) res[i] = mu;
135static vector<double> intToDosage(
const vector<int> &v,
const bool &missingToMean) {
138 vector<double> res( v.size() / 2.0);
142 int runningSum = 0, nValid = 0;
147 for(
int i=0; i<res.size(); i++){
148 value = v[2*i] + v[2*i+1];
153 value = std::numeric_limits<double>::quiet_NaN();
154 missing.push_back(i);
166 double mu = runningSum / (double) nValid;
171 for(
const int& i : missing) res[i] = mu;
181static size_t removeDuplicates(vector<T>& vec){
182 unordered_set<T> seen;
184 auto newEnd = remove_if(vec.begin(), vec.end(), [&seen](
const T& value)
186 if (seen.find(value) != end(seen))
193 vec.erase(newEnd, vec.end());
203static arma::vec colSums(
const arma::mat &X){
206 arma::rowvec ONE(X.n_rows, arma::fill::ones);
209 arma::mat tmp = ONE * X;
211 return arma::conv_to<arma::vec>::from( tmp );
223static void standardize( arma::mat &X,
const bool ¢er =
true,
const bool &scale =
true,
const double tol = 1e-10 ){
225 double sqrt_rdf = sqrt(X.n_rows - 1.0);
232 for(
size_t j=0; j<X.n_cols; j++){
233 if( center ) X.col(j) -= mean(X.col(j));
234 double sd = norm(X.col(j)) / sqrt_rdf;
235 if( scale && sd > tol ) X.col(j) /= sd;
241static void standardize( Eigen::MatrixXd &X,
const bool ¢er =
true,
const bool &scale =
true,
const double tol = 1e-10 ){
243 double sqrt_rdf = sqrt(X.rows() - 1.0);
244 if(center) X.rowwise() -= X.colwise().mean();
247 for(
size_t j=0; j<X.cols(); j++) {
248 double sd = X.col(j).norm() / sqrt_rdf ;
249 if(sd > tol) X.col(j) /= sd;
255static void standardize_rows( Eigen::MatrixXd &X,
const bool ¢er =
true,
const bool &scale =
true,
const double tol = 1e-10 ){
257 double sqrt_rdf = sqrt(X.cols() - 1.0);
258 if(center) X.colwise() -= X.rowwise().mean();
261 for(
size_t j=0; j<X.rows(); j++) {
262 double sd = X.row(j).norm() / sqrt_rdf ;
263 if(sd > tol) X.row(j) /= sd;
271static bool isOnlyDigits(
const std::string& s){
272 int n = count_if(s.begin(), s.end(),
273 [](
unsigned char c){ return isdigit(c); }
275 return( n == s.size());
281static void nanToMean( arma::vec & v){
283 arma::uvec idx = arma::find_finite(v);
286 if( idx.n_elem < v.n_elem ){
288 double mu = arma::mean( v.elem(idx));
291 v.replace(arma::datum::nan, mu);
313 case VCF:
return "vcf";
314 case VCFGZ:
return "vcf.gz";
315 case BCF:
return "bcf";
316 case BGEN:
return "bgen";
317 case PGEN:
return "pgen";
318 case PBED:
return "bed";
319 case OTHER:
return "other";
320 default:
return "other";
328static FileType getFileType(
const string &file ){
332 if( regex_search( file, regex(
"\\.vcf$")) ){
334 }
else if( regex_search( file, regex(
"\\.vcf\\.gz$")) ){
336 }
else if( regex_search( file, regex(
"\\.bcf$")) ) {
338 }
else if( regex_search( file, regex(
"\\.bgen$")) ){
340 }
else if( regex_search( file, regex(
"\\.pgen$")) ){
342 }
if( regex_search( file, regex(
"\\.bed$")) ){
354static vector<T> cast_elements(
const vector<string> &v ){
355 vector<T> output(0, v.size());
358 stringstream parser(s);
369static vector<int> stoi_vec(
const vector<string> &v ){
372 output.reserve(v.size());
374 for (
const string& s : v) {
375 output.push_back(std::stoi(s));
387static vector<string> splitRegionString(
string regionString){
391 erase_all(regionString,
" ");
392 vector<string> regions = split_any_of(regionString,
"\t,\n");
395 removeDuplicates( regions );
403template<
typename T,
typename T2>
404static vector<T> subset_vector(
const vector<T> &x,
const vector<T2> &idx){
408 x_subset.reserve(idx.size());
412 throw std::out_of_range(
"Index is out of bounds");
414 x_subset.push_back( x[i] );
422static void print_vec(
const string &title,
const vector<T> &x){
423 Rcpp::Rcout << title <<
"\n";
424 for(
auto a: x) Rcpp::Rcout << a <<
" ";
432std::vector<std::vector<T>>
chunk_vector(
const std::vector<T>& vec,
int k) {
433 std::vector<std::vector<T> > result;
434 int size = vec.size();
435 int chunk_size = size / k;
436 int remainder = size % k;
439 for (
int i = 0; i < k; ++i) {
440 int current_chunk_size = chunk_size;
442 current_chunk_size++;
444 std::vector<T> chunk(vec.begin() + start, vec.begin() + start + current_chunk_size);
445 result.push_back(chunk);
446 start += current_chunk_size;
454static vector<unsigned int> which_in(
const vector<T> &v1,
const vector<T> &v2){
457 unordered_map<T, bool> v2_elements;
459 v2_elements[x] =
true;
463 vector<unsigned int> shared_indices;
464 for (
int i = 0; i < v1.size(); ++i) {
466 if (v2_elements.count(v1[i])) {
468 shared_indices.push_back(i);
472 return shared_indices;
Definition bgenstream.h:33
FileType
Definition utils.h:298
@ OTHER
Definition utils.h:305
@ BGEN
Definition utils.h:302
@ BCF
Definition utils.h:301
@ PBED
Definition utils.h:304
@ PGEN
Definition utils.h:303
@ VCFGZ
Definition utils.h:300
@ VCF
Definition utils.h:299
std::vector< std::vector< T > > chunk_vector(const std::vector< T > &vec, int k)
Definition utils.h:432