BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
a_k93
Fluorite | Level 6

Hi Everyone,

 

Data ds_test;
    retain id name fees;
    length name$ 20.;
    input id name$ fees;
datalines;
1001 aaa 200
1002 bbb 250
1003 ccc 180
1004 ddd 220
1005 eee 200
1006 fff 210
1007 ggg 200
1008 hhh 200
;
run;

 


1. Data ds_test1;
2.    set ds_test;
3.    if fees = 200 then do;
4.        *new_name = catx("", name, "_");
5.        new_name = strip(name) || strip("_");
6.        new_name = new_name || "2";
7.    end;
8. run;

 

The new dataset (ds_test1) which I get after executing the above code contains new_name column. This new column has "_" besides the name variable records which has 200 as fees. I am intentionally adding "2" as shown at line 6 on separate line to further concatinate the new_name variable with value 2 (so that it will looks like "_2"). But It was not concatinating the "2" with "_" as shown below.

 

 1.jpg

 

Can someone tell what is it going at PDV level.

 

Thanks,

a_k93

 

1 ACCEPTED SOLUTION

Accepted Solutions
ballardw
Super User

Anything wrong with:

new_name = cats(name, "_2");

or

new_name = cats(name,"_");

new_name = cats(new_name,"2");

 

Did you run with

new_name = new_name || "2";

or

new_name = strip(new_name) || "2"

 

In the first use of var || 2 doesn't do what you want because the existing value of new_name is using all of the space allocated for new_name and tacking 2 on the end exceeds the length. It will not matter how long you make it as long as you use two steps to concatenate things.

The second, using Strip() says to ignore existing blanks on the ends of new_name and then add the '2'.

 

 

View solution in original post

9 REPLIES 9
Astounding
PROC Star

NEW_NAME has a set length in the PDV.  It doesn't have room to add "2" to the end of it.  The solution is simple though:

 

new_name = strip(new_name) || "2";

 

a_k93
Fluorite | Level 6
Thanks Astounding, but I tried adding length statement as below, but still it was not comming.
length new_name$ 20.;
ballardw
Super User

Anything wrong with:

new_name = cats(name, "_2");

or

new_name = cats(name,"_");

new_name = cats(new_name,"2");

 

Did you run with

new_name = new_name || "2";

or

new_name = strip(new_name) || "2"

 

In the first use of var || 2 doesn't do what you want because the existing value of new_name is using all of the space allocated for new_name and tacking 2 on the end exceeds the length. It will not matter how long you make it as long as you use two steps to concatenate things.

The second, using Strip() says to ignore existing blanks on the ends of new_name and then add the '2'.

 

 

a_k93
Fluorite | Level 6
Thanks ballardw.... got your point. So just to confirm when SAS execute the below statement
new_name = strip(name) || "_";
it allocates all of the space even though the actual content is only 4 characters (aaa_) and hence in the next statement when it tries to concatenate "2" with "aaa_" it does not find the space. It that what you are trying to explain correct?
Astounding
PROC Star

Right, a LENGTh statement will not help.  If NEW_NAME has a length of 20, this statement tries to add a 21st character:

 

new_name = new_name || "2";

 

There just isn't room.  That's why you need to remove the trailing blanks from new_name.  There are a variety of ways to do that ... the STRIP function is just one way.

Shmuel
Garnet | Level 18

Change you code to:

 

Data ds_test1;
   set ds_test;
        if fees = 200 then 

          new_name = catx('_', name,'2');

run;

a_k93
Fluorite | Level 6

Thanks Shmuel, it does add "_2" to the respected records but the objective of the question was to know why is it not concatinating the way it was coded (in two different lines). Even after specifying length statement.

 

 

art297
Opal | Level 21

I can't recall seeing it documented, but the following test shows what is going on:

 

Data ds_test;
  retain id name fees;
  length name$ 20.;
  input id name$ fees;
  datalines;
1001 aaa 200
1002 bbb 250
1003 ccc 180
1004 ddd 220
1005 eee 200
1006 fff 210
1007 ggg 200
1008 hhh 200
;

run;

 

Data ds_test1;
  set ds_test;
  if fees = 200 then do;
    new_name = strip(name) || "__";
    new_name = strip(new_name) ||"2";
  end;
  else new_name = strip(name) || "_____";
run;

 

Data ds_test2;
  set ds_test;
  if fees = 200 then do;
    new_name = strip(name) || "_";
    new_name = strip(new_name) ||"2";
  end;
  else new_name = strip(name) || "_____";
run;

 

In creating ds_test, the retain statement determines the order of the variables, plus changes the step functionality but, since no data is missing, the change doesn't have a noticeable effect.

 

When new_name is first created, its length becomes that of the name variable, plus the length of what is being concatenated. Any additional concatenation has no effect on the variable's length.

 

Thus, for ds_test1 the length becomes 22, but for ds_test2 it becomes 21.

 

HTH,

Art, CEO, AnalystFinder.com

 

a_k93
Fluorite | Level 6

Thanks everybody for the explanation... appreciated.

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

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
  • 9 replies
  • 948 views
  • 0 likes
  • 5 in conversation