How to reorder columns and array elements based on an array?

I'm working with a 1000x20 matrix containing weight measurements of 20 different species, ordered alphabetically. I want to plot mean weight measurements 1) separately for each species (so 20 elements), and 2) grouped based on various characteristics, like the biome (so 2-4 elements).
I created a 1x20 string with all species names (used in tick labels), and then arrays with column indices corresponding to various species, like this:
all_species = 1:20;
species_groups.biome1 = [5 6 8 10 11 12 16]; % species in biome 1
species_groups.biome2 = setdiff(all_species,species_groups.biome1); % species in biome 2
This way, I'm able to easily define input data for various figures and plot the mean weight of whichever species I want.
Now I want to change the order of species in the figure where each species is plotted separately - or preferably, in the entire dataset before any analysis is done. I have a new 1x20 string with the desired order:
new_order = [14 13 15 12 16 4 3 5 6 8 9 7 1 2 17 18 19 20 10 11];
What's the easiest way to:
1) reorder the columns in my original 1000x20 dataset based on this array, so that e.g. the species that was 14th in the original dataset would instead come first?
2) Replace all the numbers (in fact column indices) in species_groups with corresponding values from the new_order array?
Many thanks in advance for help!

 採用された回答

Dyuman Joshi
Dyuman Joshi 2024 年 2 月 21 日
"1) reorder the columns in my original 1000x20 dataset based on this array, so that e.g. the species that was 14th in the original dataset would instead come first?"
Directly use those indices -
all_species = 1:20;
species_groups.biome1 = [5 6 8 10 11 12 16]; % species in biome 1
species_groups.biome2 = setdiff(all_species,species_groups.biome1); % species in biome 2
species_groups
species_groups = struct with fields:
biome1: [5 6 8 10 11 12 16] biome2: [1 2 3 4 7 9 13 14 15 17 18 19 20]
new_order = [14 13 15 12 16 4 3 5 6 8 9 7 1 2 17 18 19 20 10 11];
data = data(:,new_order);
"2) Replace all the numbers (in fact column indices) in species_groups with corresponding values from the new_order array?"
Once again, indexing ftw -
species_groups.biome1 = new_order(species_groups.biome1); % species in biome 1
species_groups.biome2 = new_order(species_groups.biome2); % species in biome 2
species_groups
species_groups = struct with fields:
biome1: [16 4 5 8 9 7 18] biome2: [14 13 15 12 3 6 1 2 17 19 20 10 11]

5 件のコメント

Corymbiamaculata
Corymbiamaculata 2024 年 2 月 21 日
Hi, many thanks!
*1 works great, thanks! I need to adjust it a little since my dataset actually contains close to 100 columns (I mentioned the 20 relevant in this case), but with your hint I'm able to do it myself. Thanks again.
*2 doesn't work the way I need, unfortunately - index elements in species_groups ordered in the new way correspond to wrong species. For example, the first element in species_groups.biome1 was originally 5 (let's say Coccinella septempunctata) - so species listed as 5th in the alphabetical order. In the new order, I want this species to be listed at the 8th position - it's the 8th element in new_order, after 14, 13, 15, 12, 16, 4 and 3. Instead, your code replaced 5 with 16, as the 5th element in new_order is species originally listed as 16th (Tenebrio molitor). So I guess what it needs to do is to find the position of 5 in new_order and replace 5 with it. I just don't know how to do this, being horrible at indexing!
Dyuman Joshi
Dyuman Joshi 2024 年 2 月 22 日
編集済み: Dyuman Joshi 2024 年 2 月 23 日
@Corymbiamaculata, Try this for the 2nd part -
all_species = 1:20;
species_groups.biome1 = [5 6 8 10 11 12 16]; % species in biome 1
species_groups.biome2 = setdiff(all_species,species_groups.biome1); % species in biome 2
species_groups
species_groups = struct with fields:
biome1: [5 6 8 10 11 12 16] biome2: [1 2 3 4 7 9 13 14 15 17 18 19 20]
new_order = [14 13 15 12 16 4 3 5 6 8 9 7 1 2 17 18 19 20 10 11];
%get the indices of the values
[~,k] = sort(new_order)
k = 1×20
13 14 7 6 8 9 12 10 11 19 20 4 2 1 3 5 15 16 17 18
%Use the indices
species_groups.biome1 = k(species_groups.biome1);
species_groups.biome2 = k(species_groups.biome2);
species_groups
species_groups = struct with fields:
biome1: [8 9 10 19 20 4 5] biome2: [13 14 7 6 12 11 2 1 3 15 16 17 18]
Dyuman Joshi
Dyuman Joshi 2024 年 2 月 25 日
Any updates, @Corymbiamaculata?
Corymbiamaculata
Corymbiamaculata 2024 年 2 月 25 日
It works, many many thanks! :)
Dyuman Joshi
Dyuman Joshi 2024 年 2 月 25 日
You're welcome! Glad to have helped :)

サインインしてコメントする。

その他の回答 (0 件)

カテゴリ

ヘルプ センター および File ExchangeStructures についてさらに検索

製品

リリース

R2023a

タグ

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by