Loop with strings

Hi everyone,

I have a matrix nx2 where the elements in 1st column are numbers and in the second column are  strings .

How can I print the following loop ?

for i (1,n,1);
   i~vnames[i,2];
endfor;

8 Answers



0



a correction:

The loop according to previous post is:
for i (1,n,1);
i~vnames[i,2];
endfor;

The problem arises in such a case is that when you combine numbers with strings the output is not printed correctly.



0



The print command in GAUSS will allow you to provide a space delimited list of items to print. For example, the following code:

string vnames = { "Afghanistan", "Akrotiri", "Albania", "Algeria" };

for i(1, rows(vnames), 1);
   print i vnames[i];
endfor;

will print out the following:

       1.0000000 Afghanistan
       2.0000000 Akrotiri
       3.0000000 Albania
       4.0000000 Algeria

Note that the number of digits after the decimal point can be controlled by the GAUSS format statement.

If you needed to turn the number into a string--maybe to add it to a more complicated expression, report or table--you can accomplish that goal with the GAUSS function ntos which was added in version 14. For example:

string vnames = { "Afghanistan", "Akrotiri", "Albania", "Algeria" };

for i(1, rows(vnames), 1);
   print ntos(i)$~vnames[i];
endfor;

Note in the above example that $~ is the operator for horizontal string concatenation. The ntos function turns the number, i into a string.

aptech

1,773


0



 What can I do when the names are imported from an .xlsx file and it is too hard to write for example 100 names is the this way.

string vnames = { "Afghanistan", "Akrotiri", "Albania", "Algeria" ... "name100"};

Furthemore, I want to keep the results of the loop in a matrix of the form

A = {};
for i (1,n,1);
   A = A|i~vnames[i,2];
endfor

and save this matrix in .xlsx form (i.e. SpreadsheetWrite(A,file_name, "a2",1);)
ps: I use GAUSS v10



0



GAUSS allows you to place character elements inside of normal matrix entries. These are usually vectors and are referred to as character vectors. Since these character vector elements are inside of a matrix, you need to tell GAUSS to print them as characters instead of as numbers. For example:

vnames = { 11 GDP,
         12 GNP,
         13 Imports,
         14 Exports };
print vnames;

will return:

   11.000000             +DEN 
   12.000000             +DEN 
   13.000000   4.3009300e-307 
   14.000000   4.3009300e-307 

The first column looks as we would expect, however, the second column does not. The second column does not contain letters, but instead contains the numerical interpretation of the data stored in each of those respective matrix locations.

You can tell GAUSS to print an element as character data by prepending the dollar sign ($) to the value being printed. For example:

vnames = { 11 GDP,
         12 GNP,
         13 Imports,
         14 Exports };

for i(1, rows(vnames), 1);
   print i $vnames[i,2];
endfor;

will return:

   1.0000000              GDP 
   2.0000000              GNP 
   3.0000000          IMPORTS 
   4.0000000          EXPORTS 

aptech

1,773


0



You do not need to assign the string array in the manner:

string vnames = { "Afghanistan"...}

I added that just to provide a fully functional example. If you read in the string array from an Excel file with spreadSheetReadSA or create it in another way it will act the same.

It sounds like you have a matrix with one vector of numeric data and one vector of character data. You need to convert the character matrix to a string array before you write it to the Excel file. You can do this with the GAUSS function cvtosa that stands for "character vector to string array". Here is a fully functional example:

//This one assignment takes the place of your loop
my_matrix = { 11 GDP,
         12 GNP,
         13 Imports,
         14 Exports };

//write the first column with numeric data
spreadSheetWrite(my_matrix[.,1], "my_file.xls", "A2", 1);

//write the second column with text, converting
//the character vector to a string array with 'cvtosa'
spreadSheetWrite(cvtosa(my_matrix[.,2]), "my_file.xls", "B2", 1);

aptech

1,773


0



 

Let me show you want I want to do: 

file_name = ".\\outputdata_constr.xlsx";
file_name_1 = ".\\correls_constr.xlsx";
VNames = xlsReadSA(file_name_1, "A1", 2, "");  // characters vector

DATA = SpreadsheetReadM(file_name_1, "A2",1);

CORS = CORRX(DATA);
L = lowmat(CORS);

CORS_RANKING = {};

for i(2,rows(L),1);
for j(1,i-1,1);
CORS_RANKING = (CORS_RANKING|(L[i,j]~i~j));
endfor;
endfor;

CORS_RANKING = sortc(CORS_RANKING,1);

SpreadsheetWrite(CORS_RANKING,file_name, "a2",1);

I want to replace the i~j (with the names in character vector), i.e. with something like this:

CORS_RANKING = (CORS_RANKING|(L[i,j]~VNames[i]~VNames[j]));

 



0



I think the best method is to keep VNames as string data.

If you just want to keep the data and strings in vnames in the same relative order, you can do that by keeping them as separate GAUSS variables. This would change your loop to look like this:

CORS_RANKING = {};
VNames_out = {};

for i(2, rows(L), 1);
   for j(1, i-1, 1);
      CORS_RANKING = CORS_RANKING|L[i,j];
      VNames_out = VNames_out $| (VNames[i]$~VNames[j]);
   endfor;
endfor;

Notice that the GAUSS concatenation operators for strings have the dollar sign in front of them. $| for vertical concatenation of strings and $+ for horizontal concatenation of strings.

To sort both CORS_RANKING and VNames_out you will need to use the sortind command to get the indices for the sorted vector. With that output, you can sort them both with an indexing operation like this:

idx = sortind(CORS_RANKING);

//Sort both GAUSS variables
CORS_RANKING = CORS_RANKING[idx];
VNames_out = VNames_out[idx];

Once you have the data in the correct order, you can use spreadSheetWrite to write the data to the correct columns of the spreadsheet.



0



Many Thanks!!!

Your Answer

8 Answers

0

a correction:

The loop according to previous post is:
for i (1,n,1);
i~vnames[i,2];
endfor;

The problem arises in such a case is that when you combine numbers with strings the output is not printed correctly.

0

The print command in GAUSS will allow you to provide a space delimited list of items to print. For example, the following code:

string vnames = { "Afghanistan", "Akrotiri", "Albania", "Algeria" };

for i(1, rows(vnames), 1);
   print i vnames[i];
endfor;

will print out the following:

       1.0000000 Afghanistan
       2.0000000 Akrotiri
       3.0000000 Albania
       4.0000000 Algeria

Note that the number of digits after the decimal point can be controlled by the GAUSS format statement.

If you needed to turn the number into a string--maybe to add it to a more complicated expression, report or table--you can accomplish that goal with the GAUSS function ntos which was added in version 14. For example:

string vnames = { "Afghanistan", "Akrotiri", "Albania", "Algeria" };

for i(1, rows(vnames), 1);
   print ntos(i)$~vnames[i];
endfor;

Note in the above example that $~ is the operator for horizontal string concatenation. The ntos function turns the number, i into a string.

0

 What can I do when the names are imported from an .xlsx file and it is too hard to write for example 100 names is the this way.

string vnames = { "Afghanistan", "Akrotiri", "Albania", "Algeria" ... "name100"};

Furthemore, I want to keep the results of the loop in a matrix of the form

A = {};
for i (1,n,1);
   A = A|i~vnames[i,2];
endfor

and save this matrix in .xlsx form (i.e. SpreadsheetWrite(A,file_name, "a2",1);)
ps: I use GAUSS v10

0

GAUSS allows you to place character elements inside of normal matrix entries. These are usually vectors and are referred to as character vectors. Since these character vector elements are inside of a matrix, you need to tell GAUSS to print them as characters instead of as numbers. For example:

vnames = { 11 GDP,
         12 GNP,
         13 Imports,
         14 Exports };
print vnames;

will return:

   11.000000             +DEN 
   12.000000             +DEN 
   13.000000   4.3009300e-307 
   14.000000   4.3009300e-307 

The first column looks as we would expect, however, the second column does not. The second column does not contain letters, but instead contains the numerical interpretation of the data stored in each of those respective matrix locations.

You can tell GAUSS to print an element as character data by prepending the dollar sign ($) to the value being printed. For example:

vnames = { 11 GDP,
         12 GNP,
         13 Imports,
         14 Exports };

for i(1, rows(vnames), 1);
   print i $vnames[i,2];
endfor;

will return:

   1.0000000              GDP 
   2.0000000              GNP 
   3.0000000          IMPORTS 
   4.0000000          EXPORTS 
0

You do not need to assign the string array in the manner:

string vnames = { "Afghanistan"...}

I added that just to provide a fully functional example. If you read in the string array from an Excel file with spreadSheetReadSA or create it in another way it will act the same.

It sounds like you have a matrix with one vector of numeric data and one vector of character data. You need to convert the character matrix to a string array before you write it to the Excel file. You can do this with the GAUSS function cvtosa that stands for "character vector to string array". Here is a fully functional example:

//This one assignment takes the place of your loop
my_matrix = { 11 GDP,
         12 GNP,
         13 Imports,
         14 Exports };

//write the first column with numeric data
spreadSheetWrite(my_matrix[.,1], "my_file.xls", "A2", 1);

//write the second column with text, converting
//the character vector to a string array with 'cvtosa'
spreadSheetWrite(cvtosa(my_matrix[.,2]), "my_file.xls", "B2", 1);
0

 

Let me show you want I want to do: 

file_name = ".\\outputdata_constr.xlsx";
file_name_1 = ".\\correls_constr.xlsx";
VNames = xlsReadSA(file_name_1, "A1", 2, "");  // characters vector

DATA = SpreadsheetReadM(file_name_1, "A2",1);

CORS = CORRX(DATA);
L = lowmat(CORS);

CORS_RANKING = {};

for i(2,rows(L),1);
for j(1,i-1,1);
CORS_RANKING = (CORS_RANKING|(L[i,j]~i~j));
endfor;
endfor;

CORS_RANKING = sortc(CORS_RANKING,1);

SpreadsheetWrite(CORS_RANKING,file_name, "a2",1);

I want to replace the i~j (with the names in character vector), i.e. with something like this:

CORS_RANKING = (CORS_RANKING|(L[i,j]~VNames[i]~VNames[j]));

 

0

I think the best method is to keep VNames as string data.

If you just want to keep the data and strings in vnames in the same relative order, you can do that by keeping them as separate GAUSS variables. This would change your loop to look like this:

CORS_RANKING = {};
VNames_out = {};

for i(2, rows(L), 1);
   for j(1, i-1, 1);
      CORS_RANKING = CORS_RANKING|L[i,j];
      VNames_out = VNames_out $| (VNames[i]$~VNames[j]);
   endfor;
endfor;

Notice that the GAUSS concatenation operators for strings have the dollar sign in front of them. $| for vertical concatenation of strings and $+ for horizontal concatenation of strings.

To sort both CORS_RANKING and VNames_out you will need to use the sortind command to get the indices for the sorted vector. With that output, you can sort them both with an indexing operation like this:

idx = sortind(CORS_RANKING);

//Sort both GAUSS variables
CORS_RANKING = CORS_RANKING[idx];
VNames_out = VNames_out[idx];

Once you have the data in the correct order, you can use spreadSheetWrite to write the data to the correct columns of the spreadsheet.

0

Many Thanks!!!


You must login to post answers.

Have a Specific Question?

Get a real answer from a real person

Need Support?

Get help from our friendly experts.