Armadillo C++:基于另外两个向量对一个向量进行排序
Efficient Multi-Level Sorting in Armadillo C++ (Matching R's
order(b,c)) Absolutely! Armadillo provides a clean, optimized way to replicate R's multi-level sorting behavior (a[order(b,c)])—and it’s way faster for large datasets than pure R implementations. Let’s walk through exactly how to do this, with a working example matching your R code.
Step-by-Step Implementation
The core idea is to use Armadillo's sort_index() function, which natively handles multi-column sorting (sort by one key first, then break ties with another). Here's how to map your R workflow to C++:
- Define your input vectors (matching your R example data)
- Combine sort keys into a matrix: Armadillo’s
sort_index()accepts a matrix where each column represents a sort priority (first column = primary key, second = secondary key) - Generate sorted indices: Get the indices that would sort the key matrix (first by
b, then byc) - Reorder vector
a: Use the sorted indices to rearrangeaexactly like R’sa[order(b,c)]
Full Working Code
#include <armadillo> using namespace arma; int main() { // Match your R example data vec a = {1, 2, 3, 4, 5}; vec b = {1, 2, 1, 2, 1}; vec c = {5, 4, 3, 2, 1}; // Combine b and c into a 2-column matrix (primary key = b, secondary = c) mat sort_keys = join_rows(b, c); // Get indices that sort the matrix: first by column 1 (b), then column 2 (c), ascending order uvec sorted_indices = sort_index(sort_keys, "ascend"); // Reorder vector a using the sorted indices vec sorted_a = a(sorted_indices); // Print the result to verify (should match R's output: 5 3 1 4 2) sorted_a.print("Sorted a:"); return 0; }
Key Details & Optimization Notes
- Sort Order: The
"ascend"parameter is the default, so you can omit it if you want. To sort a key in descending order, negate the vector (e.g.,join_rows(-b, c)to sortbdescending) or use"descend"(applies to all columns). - Efficiency: Armadillo’s
sort_index()uses highly optimized IntroSort under the hood, which is significantly faster than R’s interpreted sorting for large datasets (especially with vectors of length 10,000+). - Data Types: If your vectors are integers, use
ivecinstead ofvecfor better memory efficiency—Armadillo handles all numeric types seamlessly withsort_index(). - Alternative Stable Sort: If you prefer a two-step approach, you can first sort by
c, then do a stable sort byb:
That said, the singleuvec idx_c = sort_index(c); vec a_sorted_c = a(idx_c); vec b_sorted_c = b(idx_c); uvec idx_b = sort_index(b_sorted_c, "ascend", true); // true = stable sort vec sorted_a = a_sorted_c(idx_b);sort_index()call on the combined matrix is more efficient, as it handles both keys in one pass.
Verification
When you run the code above, the output will be:
Sorted a: 5.0000 3.0000 1.0000 4.0000 2.0000
Which exactly matches your R example’s a[order(b,c)] result.
内容的提问来源于stack exchange,提问作者Jack4280
相关产品推荐
相关产品推荐

