Getting Variables from a data structure and creating a matrix from those variables - matlab

I have a data structure which has data points named Vel1 to Vel1520. However, when I apply Uorder = orderfields(MeanU_Velocity); the variables put in the order Vel1 Vel10 Vel100 Vel1000 Vel1001 Vel1002 etc. Is there any way to sort the data structure such that it lists the variables from 1 to 1520 in ascending order? Regards, Jer

An easy fix to this is to always use the same number of digits. 0001, 0002, ..., 0010, ..., 1520

instead of num2str(42), try sprintf('Vel%04d', 42). This prints formatted text to a string. %04d is a special code that says: fill with zeros, reserve 4 places, print an integer number. Have a look at the documentation and look at matlabs formatted strings tutorial for more comprehensive examples.

Related

Can I directly load text with numbers in CCC,CC format ? (K4)

I have input with floats stored like 1000,50, ie. the decimal points are replaced by commas.
Is there an option in K to load these numbers directly into floats ?
When using
data:("SFF" ;";",";") 0:. filename
I get 0ns, of course, because the numbers are not recognized as floats.
I load them as strings now, and convert them using ssr like
c:.:' .q.ssr'[data;",";"."]
but that is extremely slow.
Is there an option somewhere to have K load these numbers in CCC,CC format as floats directly ? Normal format and ccc,cc format are not mixed, any file has just one of them.
If there is not, I imagine that it must by quite easy to replace a "." somewhere in the Q-binary where the load-function sits, with a ",", to get a version which loads these numbers. Has anybody tried that ? Or any other tip to load big files with these numbers in reasonable time ?
Cheers,
Co
If ssr' is slow for your task you may find this tiny function useful:
c2p:{c:-1_sums count each x;p:ss[r:raze x;","];r[p]:".";(0,c) _ r}
Update: an alternative version:
c2p:{p:ss[r:raze x;","];r[p]:".";(0,-1_sums count'[x])_r}
It concatenates all strings into a single long string, finds positions of commas, replaces commas with periods then splits that long string:
q)N:1000000
q)s:string[N?100000],'",",'string N?1000
q)\t r1:ssr'[s;",";"."]
4284
q)\t r2:c2p s
242
q)r1~r2
1b
I was thinking something like find (?) combined with indexing/applying
q)N:1000000
q)s:string[N?100000],'",",'string N?1000
q)\ts {s[x;y]:"."}./:flip(til count s;s?\:",")
967 52972144
q)s
"93912.794"
"57144.788"
"77809.659"
"7839.47"
"6363.523"
"44761.244"
"65699.712"
It's not perfect but that's the general idea. I'm sure there is an easier way...

Sorting Data in Matlab

I am trying to sort the following data in the Matlab, but not getting the expected output what I need.
Here is data:
'1B-3A-5A'
'1A-3A-19A'
'2A-2A-4A-5A'
'2B-2A-5A'
'2A-4A-5A'
'2C-5A-30A'
'11A-3A-19A
'3A-19A-42C'
'4A-4A-12A'
'19A-21A-42C'
'25A-41D'
'41C-41C'
'39C-41C'
'43E'
'39A-41D'
'1A-3A-5A-7A'
'7C-27A-28A'
I need the sorted list such that it considers the first number then the alphabet to sort the list like below
'1A-3A-19A'
'1A-3A-5A-7A'
'1B-3A-5A'
'2A-2A-4A-5A'
'2A-4A-5A'
'2B-2A-5A'
'2C-5A-30A'
'3A-19A-42C'
'4A-4A-12A'
'7C-27A-28A'
'11A-3A-19A
'19A-21A-42C'
'25A-41D'
'39A-41D'
'39C-41C'
'41C-41C'
'43E'
Can you please suggest a way to do it? I tried all ways but it doesn't sort it like I want. Thanks!!
How about using sort or sortrows? This does actually sort strings as well:
If A is a string, then sort(A) sorts according to the ASCII dictionary order. The sort is case sensitive with uppercase letters appearing in the output before the lowercase letters.
As #StewieGriffin pointed out, this sorts 11a before 1a. Conveniently Douglas Schwarz has already produced a code that overcomes exactly this problem of alphanumeric sorting on numerics first and characters after.

How to use numbers as delimiters in MATLAB strsplit function

As the title suggests I'm looking to detect where the numbers are in a string and then to just take the substring from the larger string. EG
If I have say zero89 or eight78, I would just like zero or nine returned. When using the strsplit function I have:
strsplit('zero89', but what do I put here?)
Interested in regexp that will provide you more options to explore with?
Extract numeric digits -
regexp('zero89','\d','match')
Extract anything other than digits -
regexp('zero89','\d+','Split')
strsplit('zero89', '\d', 'DelimiterType', 'RegularExpression')
Or just using regexp:
regexp('zero89','\D+','match')
I got the \D+ from here
Assuming you mean this strsplit?
strsplit('zero89', '8')

MATLAB: Reference iterated strings in variable names in Stata style

In MATLAB, I want to perform a series of commands on a pair of datasets which group males and females separately -- and I want to export the results separately. I'm familiar with Stata, so my instinct is to do something like this:
foreach X in m f{
data_`X' = csvread('data_`X'.csv');
variable_`X' = data_`X'(:,12);
plot(1975:2011,variable_`X')
print -djpeg graph_`X'
% etc.
}
but I haven't been able to find an analog to that `X' quoting structure in MATLAB, which would allow the iterated string to be referred to as a part of a variable name.
I'm new to MATLAB, so I may be barking up the wrong tree entirely. Any ideas?
You can do this, but it may not be the most efficient.
Assuming that m is a cell array of strings, and data_X.csv exists:
for ii=1:length(m)
assignin('base',['data_' m{ii}], csvread(evalin('base',['data_' m{ii} '.csv'));
assignin('base',['variable_' m{ii}],['data_' m{ii} '(:,12)']);
plot(1975:2011, evalin('base',['variable_' m{ii}]));
...
I think that will get you on the right track.

How to randomly select from a list of 47 names that are entered from a data file?

I have managed to input a number data file into a matrix but have been unable to do so for any data that is not a number.
I have a list of 47 names and supposed to generate a random name from the list. I have tried to use the function textscan but was not going anywhere. Also how do I generate a random name from the list? All I have been able to do was generate a random number between 1 to 47.
Appreciate the replies. I should have said I need it in MATLAB sorry.
Here is a sample list of data in my data file
name01
name02
name03
and the code to read it:
fid = fopen('names.dat','rt');
headerChars = fgetl(fid);
data = fscanf(fid,'%f,%f,%f,%f',[4 47]).';
fclose(fid);
The above is what I have to read the data file into a matrix but it is only reading the first line. (Yes it was modified from a previous post here on this forums :/)
Edit: As per the helpful comments from mtrw, and the fixed formatting of the sample data file, I've updated my answer with more detail.
With a single name (i.e. "Bob", "Bob Smith", or "Smith, Bob") on each line of the file, you can use the function TEXTSCAN by specifying '%s' as the format argument (to denote reading a string) and the newline character '\n' as the 'Delimiter' (the character that separates the strings in the file):
fid = fopen('namefile.txt','r');
names = textscan(fid,'%s','Delimiter','\n');
fclose(fid);
Then it's a matter of randomly picking one of the names. You can use the function RANDI to generate a random integer in the range from 1 to the number of names read from the file (found using the NUMEL function):
names = names{1}; %# Get the contents from the cell returned by TEXTSCAN
selectedName = names{randi(numel(names))};
Sounds like you're halfway home. Take that random number and use it as an index for the list.
For example, if you randomly generate the number 23 then fetch the 23rd entry in the list which gives you a random name draw.
Use the RANDOMBETWEEN function to get a random number within your range. Use INDEX to get the actual cell value. For instance:
=INDEX(A1:A47, RANDBETWEEN(1, 47))
The above will work for your specific case of 47 names, assuming they're in column A. In general, you'd want something like:
=INDEX(MyNames, RANDBETWEEN(ROW(MyNames), ROW(MyNames) + ROWS(MyNames) - 1))
This assumes you've named your range of cells "MyNames" (for example, by selecting all the cells in your range and setting a name in the naming box). The above formula works by using the ROW function to return the top row of the MyNames array and the ROWS function to get the total rows in MyNames.