| 244 | } |
| 245 | |
| 246 | void quantileNormalize(std::vector<std::vector<double>>& data) { |
| 247 | int cellCount = data.size(); |
| 248 | int binCount = data[0].size(); |
| 249 | |
| 250 | //First calculate rank means |
| 251 | std::vector<double> rankedMean(binCount,0); |
| 252 | for(int cellID = 0; cellID < cellCount; cellID++) { |
| 253 | std::vector<double> x(binCount,0); |
| 254 | for(int binID = 0; binID < binCount; binID++) { |
| 255 | x[binID] = data[cellID][binID]; |
| 256 | } |
| 257 | |
| 258 | sort(x.begin(), x.end()); |
| 259 | |
| 260 | for(int binID = 0; binID < binCount; binID++) { |
| 261 | rankedMean[binID] += x[binID]; |
| 262 | } |
| 263 | } |
| 264 | for(int binID = 0; binID < binCount; binID++) { |
| 265 | rankedMean[binID] /= (double)cellCount; |
| 266 | } |
| 267 | |
| 268 | //calculate half value for ties |
| 269 | std::vector<double> rankedMeanTie(binCount-1,0); |
| 270 | for(int binID = 0; binID < (binCount-1); binID++) { |
| 271 | rankedMeanTie[binID] = ((rankedMean[binID]+rankedMean[binID+1])/2); |
| 272 | } |
| 273 | |
| 274 | //Iterate through each cell line |
| 275 | for(int s = 0; s < cellCount; s++) { |
| 276 | std::vector<double> bins(binCount,0); |
| 277 | for(int p = 0; p < binCount; p++) { |
| 278 | bins[p] = data[s][p]; |
| 279 | } |
| 280 | rankify(bins); |
| 281 | |
| 282 | std::vector<double> binsQuantileNormalized(binCount, 0); |
| 283 | for(int p = 0; p < binCount; p++) { |
| 284 | if(std::fmod(bins[p],1) != 0) { |
| 285 | binsQuantileNormalized[p] = rankedMeanTie[(int)floor(bins[p])-1]; |
| 286 | } else { |
| 287 | binsQuantileNormalized[p] = rankedMean[(int)(bins[p]-1)]; |
| 288 | } |
| 289 | |
| 290 | data[s][p] = binsQuantileNormalized[p]; |
| 291 | } |
| 292 | } |
| 293 | |
| 294 | } |
| 295 | |
| 296 | |
| 297 |
no test coverage detected