I am creating a program which opens an image, and uses the MATLAB ginput command to store x and y coordinates, which are operated on in the loop to fulfill requirements of an if statement and output a number or string corresponding to the region clicked during the ginput session. At the same time, I am using the input command to input a string from the command window relating to these numbers. The ginput session is placed in a while loop so a click in a specific area will end the input session. For each session (while loop), only one or two inputs from the command window are needed. Finally, I am trying to store all the data in a csv or txt file, but I would like it to be tabulated so it is easy to read, i.e. rows and columns with headers. I am including some sample code. My questions are: 1, how can an input of x and y coordinates be translated to a string? It is simple to do this for a number, but I cannot get it to work with a string. 2, any help on printing the strings and number to a tabulated text or cdv file would be appreciated.
Command line input:
prompt='Batter:';
Batter=input(prompt,'s');
While Loop:
count=1;
flag=0;
while(flag==0)
[x,y]= ginput(1);
if (y>539)
flag=1;
end
if x<594 && x>150 && y<539 && y>104
%it's in the square
X=x;
Y=y;
end
if x<524 && x>207 && y<480 && y>163
result='strike'
else
result='ball'
end
[x,y]= ginput(1);
pitch=0;
if x<136 && x>13
%its' pitch column
if y<539
pitch=6;
end
if y<465
pitch=5;
end
if y<390
pitch=4;
end
if y<319
pitch=3;
end
if y<249
pitch=2;
end
if y<175
pitch=1;
end
end
if pitch==0
else
plot(X,Y,'o','MarkerFaceColor',colors(pitch),'MarkerSize',25);
text(X,Y,mat2str(count));
end
count=count+1
M(count,:)=[X,Y,pitch];
end
For the above series of if statements, I would prefer a string output rather than the numbers 1-6 if the condition is satisfied.
The fprintf function is used to print to a file, but I have issues combining the strings and numbers using it:
fileID = fopen('pitches.csv','w');
fid = fopen('gamedata.txt','w');
fmtString = [repmat('%s\t',1,size(Batter,2)-1),'%s\n'];
fprintf(fid,fmtString,Batter,result);
fclose(fid);
for i=1:length(M)
fprintf(fileID,'%6.2f %6.2f %d\n',M(i,1),M(i,2),M(i,3));
end
fclose(fileID);
I have tried adding the string handles to the fprintf command along with the columns of M, but get errors. I either need to store them in an array (How?) and print all the array columns to the file, or use some other method. I also tried a version of the writetable method:
writetable(T,'tabledata2.txt','Delimiter','\t','WriteRowNames',true)
but I can't get everything to work right. Thanks very much for any help.
Let's tackle your questions one at a time:
1, how can an input of x and y coordinates be translated to a string?
You can use the sprintf command in MATLAB. This takes exactly the same syntax as fprintf, but the output of this function will give you a string / character array of whatever you desire.
2, any help on printing the strings and number to a tabulated text or cdv file would be appreciated.
You can still use fprintf but you can specify a matrix as the input. As such, you can do this:
fprintf(fileID,'%6.2f %6.2f %d\n', M.');
This will write the entire matrix to file. However, care must be taken here because MATLAB writes to files in column major format. This means that it will traverse along the rows before going to the next column. If you want to write data row by row, you will need to transpose the matrix first so that when you are traversing down the rows, it will basically do what you want. You will need to keep this in mind before you start trying to write strings to an file. What I would recommend is that you place each string in a cell array, then loop through each element in the cell array and write each string individually line by line.
Hopefully this helps push you in the right direction. Reply back to me in a comment and we can keep talking if you need more help.
Related
I have a string variable with comma separated numbers that I want to split into four numeric variables.
makeArr
var1a
var1b
var1c
var1d
6,8,13,10
6
8
13
10
10,11,2
10
11
2
7,1,14,3
7
1
14
3
With:
IF (CHAR.INDEX(makeArr,',') >= 1)
f12a=CHAR.SUBSTR(makeArr,1,CHAR.INDEX(makeArr,',')-1).
EXECUTE.
IF (CHAR.INDEX(makeArr,',') >= 1)
f12b=CHAR.SUBSTR(makeArr,CHAR.INDEX(makeArr,',')+1,CHAR.INDEX(makeArr,',')-1).
EXECUTE.
I always get the first variable written without any problems.
This no longer works with the second variable because it has a different length and the comma is also written here.
So I would need a split at the comma and the division of the numbers over the comma.
Since char.substr will only tell you about the location of the first occurence of the search string, you need to start the second search from a new location - AFTER the first occurence, and this gets more and more complicated as you continue. My suggestion is create a copy of your array variable, which you will cut pieces off as you proceed - so that you are only searching for the first occurence of "," every time.
First I recreate your example data to demonstrate on.
data list free/makeArr (a20).
begin data
"6,8,13,10" "10,11,2" "7,1,14,3"
end data.
Now I copy your array into a new variable #tmp. Note that I add a "," at the end so the syntax stays the same for all parts of the array. I add the "#" at the beginning of the name to make it invisible, you can remove it if you want.
It is possible to do the following calculation in steps as you started to do, but nicer to loop throug the steps (especially if this is an example for a longer array).
string f12a f12b f12c f12d #tmp (a20).
compute #tmp=concat(rtrim(makeArr),",").
do repeat nwvr=f12a f12b f12c f12d.
do IF #tmp<>"".
compute nwvr=CHAR.SUBSTR(#tmp,1,CHAR.INDEX(#tmp,',')-1).
compute #tmp=CHAR.SUBSTR(#tmp,CHAR.INDEX(#tmp,',')+1).
end if.
end repeat.
EXECUTE.
Here I found a different solution for what I think is the same problem:
https://www.ibm.com/mysupport/s/question/0D50z00006PsP3tCAF/splitting-a-string-variable-divided-by-commas-into-new-single-variables?language=es
One line of code makes the work:
spssinc trans result=var_1 to var_4 type=20/formula 're.split(", *", makeArr)'.
i wrote a python program in order to list all the tweets in a Excel file which contains the word "grammy", but it didn't work, and i don't know how to modify it.
In this case, line contains a list of strings. You can iterate over each cell value in line and search for your keyword as follows:
for line in csvdata:
for cell in line:
if 'grammy' in cell:
print('this line contains my word:', line)
The problem with your approach is you initialize the counter variable i, then increment that variable, but you never reset the value of i to zero. If you want to use your approach, you'd need to reset the i counter variables to 0 for each line:
for line in csvdata:
i = 0
t = t + 1
i = i + 1
... [ rest of your code ]
If you don't reset i for each line, then the first line will increase i by 1, and all subsequent lines will just keep increasing the value of i. Eventually this will cause the index error that you're wisely catching!
Another problem with this approach is each line only checks a single value for i. So for each row, you're only checking a single cell's value. One way around this is to use the for loop approach I list above (for cell in line). Another way would be to use a while loop, but if you're new to programming I'd start by mastering the for loop before you move on to while loops.
I hope this helps!
I have a MATLAB structure with 19 fields. The main field is a 1 x 108033 double with all values numeric. It looks like this, basically 108033 numbers:
pnum: 5384940 5437561 5570271 5661637 5771155 ...
I have another field called inventors which is a 1 x 108033 cell value. Every cell contains a different number of strings. Columns 1 to 5 for example are
inventors: {2x1 cell} {4x1 cell} {1x1 cell} {1x1 cell} {1x1 cell}
For the first column value, the 2 x 1 cell consists of the following values
5012491-01 and 2035147-03 and so on.
I'd like to jointly export these two to a CSV file. The ideal outcome would repeat the number in pnum so that it establishes a clear link between the pnum and the inventors. Thus, the ideal outcome would look something like this (with the contents of what is in the inventors cell displayed).
pnum inventors
5384940 5012491-01
5384940 2035147-03
5437561 5437561-01
5437561 5437561-02
5437561 5437561-03
5437561 5012491-02
5570271 5437561-03
5661637 1885634-08
5771155 5012491-01
I asked a more complex version of this question before but it was not clear enough what the problem was. Hope it is now.
I'm assuming each cell in inventors is a cell array of strings. It wouldn't make sense for these to be actual floating point or intenger numbers, because the dash would subtract the two numbers separating them together. Now, because you're writing to a CSV file, the easiest thing I can think of is to iterate over each number and cell, then repeat the ID number for as many times as there are elements in a cell. First create the right headers, then write your results. Something like this comes to mind:
f = fopen('data.csv', 'w'); %// Open up data for writing
fprintf(f, 'pnum,inventors\n'); %// Write headers
for ii = 1 : numel(pnum) %// For each unique number
inventor = inventors{ii};
for jj = 1 : numel(inventor) %// For each inventor ID
fprintf(f, '%d,%s\n', pnum(ii), inventor{jj}); %// Write the right combo to file
end
end
fclose(f); %// Close the file
fopen here opens up a file called data.csv so we can write things to it. What is returned is a file pointer called f, which we use to write stuff to this file. After, we write the headers of the file, consisting of pnum and inventors. This is a CSV file so there's a comma separating the two. Now, for each unique number, we then access the right slot in inventors then for each unique inventor, add the same unique ID with the right inventor ID as a line in this file. I use fprintf to write things to file using the associated file pointer established earlier. Once we're done, close the file with fclose.
To double check that this works, I've used the small example you've provided in your post:
pnum = [5384940 5437561 5570271 5661637 5771155];
inventors = {{'5012491-01', '2035147-03'}.', {'5437561-01', '5437561-02', '5437561-03', '5012491-02'}.', {'5437561-03'}, {'1885634-08'}, {'5012491-01'}};
Bear in mind that I don't have access to your struct, so you'll have to access the right fields and assign them to the corresponding variables seen above. So if your struct is called something like data, then you'd do this before you run the above code:
pnum = data.pnum;
inventors = data.inventors;
Running the above code I just wrote and opening up the CSV file (which is called data.csv), I get this:
pnum,inventors
5384940,5012491-01
5384940,2035147-03
5437561,5437561-01
5437561,5437561-02
5437561,5437561-03
5437561,5012491-02
5570271,5437561-03
5661637,1885634-08
5771155,5012491-01
I want to write a function that loads a text file and plots its content with time. I have 20 text files so I want to be able to choose from them.
My current not working code:
TextFile is a generic variable
text123.txt is the actual name of one of the files i want to load
function []= PlotText(TextFile)
text(1,:)=load('text123.txt') ;
t=0:10;
plot(t,text)
end
I appreciate any help!!
use importdata instead of load with appropriate delimiter. I assume you used Tab.
filename = 'num.txt';
delimiterIn = '\t';
text = importdata(filename,delimiterIn)
t=1:10;
plot(t,text);
Firstly, you can also use dlmread if your file contains only numeric data separated by the same symbol (called a delimiter) such as a comma (,), semicolon (;), space ( ), or tab ( ). This would look like:
function []= PlotText(TextFile)
text(1,:)=dlmread('text123.txt');
t=0:10;
plot(t,text)
end
Keep in mind that your code is written in a way that expects the contents of text123.txt to have 11 values in a single row. Also, if you are using multiple files, then I suggest having the file name be another input to the function:
function []= PlotText(TextFile,filename)
text(1,:)=load(filename) ;
t=0:10;
plot(t,text)
end
I don't know if Matlab can do this, but I want to store some strings in a 4×3 matrix, each element in the matrix is a string.
test_string_01 test_string_02 test_string_03
test_string_04 test_string_05 test_string_06
test_string_07 test_string_08 test_string_09
test_string_10 test_string_11 test_string_12
Then, I want to write this matrix into a plain text file, either comma or space delimited.
test_string_01,test_string_02,test_string_03
test_string_04,test_string_05,test_string_06
test_string_07,test_string_08,test_string_09
test_string_10,test_string_11,test_string_12
Seems like matrix data type is not capable of storing strings. I looked at cell. I tried to use dlmwrite() or csvwrite(), but both of them only accept matrices. I also tried cell2mat() first, but in that way all letters in the strings are comma seperated, like
t,e,s,t,_,s,t,r,i,n,g,_,0,1,t,e,s,t,_,s,t,r,i,n,g,_,0,2,t,e,s,t,_,s,t,r,i,n,g,_,0,3
So is there any way to achieve this?
It is possible to shorten yuk's solution a bit.
strings = {
'test_string_01','test_string_02','test_string_03'
'test_string_04','test_string_05','test_string_06'
'test_string_07','test_string_08','test_string_09'
'test_string_10','test_string_11','test_string_12'};
fid = fopen('output.txt','w');
fmtString = [repmat('%s\t',1,size(strings,2)-1),'%s\n'];
fprintf(fid,fmtString,strings{:});
fclose(fid);
Cell array is the way to store strings.
I agree it's a pain to save strings into a text file, but you can do it with this code:
strings = {
'test_string_01','test_string_02','test_string_03'
'test_string_04','test_string_05','test_string_06'
'test_string_07','test_string_08','test_string_09'
'test_string_10','test_string_11','test_string_12'};
fid = fopen('output.txt','w');
for row = 1:size(strings,1)
fprintf(fid, repmat('%s\t',1,size(strings,2)-1), strings{row,1:end-1});
fprintf(fid, '%s\n', strings{row,end});
end
fclose(fid);
Substitute \t with , to get csv file.
You can also store cell array of strings into Excel file with XLSWRITE (requires COM interface, so it's on Windows only):
xlswrite('output.xls',strings)
In most cases you can use the delimiter ' ' and get Matlab to save a string into file with dlmwrite.
For example,
output=('my_first_String');
dlmwrite('myfile.txt',output,'delimiter','')
will save a file named myfile.txt containing my_first_String.