BookmarkSubscribeRSS Feed
varunnakra
Fluorite | Level 6

Hi,

I have to concatenate the values of different macro variables and make a list of them.

The following code gives the value of Node as null/blank. It's not able to concatenate the null value of Node with another text

data test1;

length Node $5.;

Node = ' ';

Node = Node ||"A";

run;

Even if I use an initial value of Node as 'X'. It doesn't concatenate 'X' with 'A'. The following code gives the value of Node as X

data test1;

length Node $5.;

Node = 'X ';

Node = Node ||"A";

run;

    

I wanted to make just one variable Node and use it recursively (referring to its previous value each time), but since the above code wasnt working properly, I made separate variables each time and wrote the following code

options symbolgen mlogic;
options compress = yes;

%let C1 = A;
%let C2 = B;
%let C3 = C;
%let C4 = D;

%macro test;
data test;
length Node1 $5.;
Node1 = "&C1";
%do i = 2 %to 4;
/*%if &i = 1 %then %let j = &i;*/
/*%else*/ %let j = %eval(&i-1);
Node&i = Node&j || " &&C&i";
%end;
run;

%mend;

%test

The above does give an output value of Node4 as A   B C D but uses 3 spaces between A and B but 1 space (as used in the code) between B, C and D, etc.

Why dont the previous codes work? Why does the above code give 3 spaces between A and B.

Please advise!

6 REPLIES 6
art297
Opal | Level 21

You have to account for leading and trailing blanks and the fact that char fields are right filled with blanks.  How about something like:

data test1;

length Node $5.;

Node = ' ';

Node = compbl(Node) ||"A";

run;

data test1;

length Node $5.;

Node = 'X ';

Node = compbl(Node)||"A";

run;

   

%let C1 = A;

%let C2 = B;

%let C3 = C;

%let C4 = D;

%macro test;

data test;

length Node1 $5.;

Node1 = "&C1";

%do i = 2 %to 4;

/*%if &i = 1 %then %let j = &i;*/

/*%else*/ %let j = %eval(&i-1);

Node&i = compbl(Node&j) || " &&C&i";

%end;

run;

%mend;

%test

FredrikE
Rhodochrosite | Level 12

Start using the "cat"-functions, really useful....:-)

options symbolgen mlogic;
options compress = yes;

%let C1 = A;
%let C2 = B;
%let C3 = C;
%let C4 = D;


%macro test;
data test;
length Node1 $5.;
Node1 = "&C1";
Nodes1 = "&C1";
%do i = 2 %to 4;
/*%if &i = 1 %then %let j = &i;*/
/*%else*/ %let j = %eval(&i-1);
Node&i =catx(' ',Node&j,"&&C&i");
Nodes&i =cats(Nodes&j,"&&C&i");
%end;
run;

%mend;

%test

//Fredrik

Astounding
PROC Star

You have some viable solutions posted.  I'm going to focus more on your final question:  Why?

This combination of statements assigns a 5-character value to NODE:

length node $ 5;

node='X';

SAS is storing "X" plus four additional blanks.

Now this expression is generating six characters:

node = node || 'A';

To the right of the equal sign is "X" then four blanks, then "A".  Since NODE is already defined as 5 characters long by the LENGTH statement, there is only room to store the first five characters of the assigned value.  So "A" cannot be added, and it looks like your statement does nothing.

As has been suggested, functions will handle the extra blanks, such as:

node = catx(' ', node, 'A');

Good luck.


varunnakra
Fluorite | Level 6

Thanks a lot everyone for the insights Smiley Happy

CarolB
Fluorite | Level 6

I was able to get the code to work by adding a trim statement:

data test1;

length Node $5.;

Node = ' ';

Node = trim(Node) ||"A";

Node = trim(Node) ||"B";

Node = trim(Node) ||"C";

Node = trim(Node) ||"D";

Node = trim(Node) ||"E";

run;

Haikuo
Onyx | Level 15

Well, if you look closer, you will find out that Trim() will only remove those trailing blanks, as a result, you will NOT get 'ABCDE', instead, you are only getting ' ABCD', as trim() will generate a character of length at least 1. Here, strip() or compress() will be better options for your purpose, otherwise, you will have to use the combination of trim() and left() to do the same: trim(left()).

HTH,

Haikuo

Update: trim() will work if you modify the first concatenate statement: Node = "A" ||trim(Node);  That will safely put 'blanks', if there are, at the end, so trim() can take care of it.

sas-innovate-2024.png

Don't miss out on SAS Innovate - Register now for the FREE Livestream!

Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.

 

Register now!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 6 replies
  • 2309 views
  • 3 likes
  • 6 in conversation