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

Having trouble getting a CAT function to work. I am trying to concatenate lines based on a ptr and lag_ptr. Here is my input and code

OPTIONS NOCENTER;                  

DATA RawData;                      

INPUT ptr lag_ptr full $5 lead $7;

datalines;                        

0 0 A B                            

0 0 B C                            

5 0 C D                            

5 5 D E                            

0 5 E F                            

0 0 F G                            

;                                  

 

DATA want; SET RawData;                  

FORMAT cat_line $CHAR05.; cat_line = " ";

IF ptr = 0 THEN DO;                      

   cat_line=full;                        

END;                                    

ELSE DO;                                

   IF lag_ptr = 0 THEN DO;              

     cat_line=CATT(full,lead);          

   END;                                  

   ELSE DO;                              

     cat_line=CATT(cat_line,lead);      

   END;                                  

END;                                    

IF lag_ptr > 0 THEN DELETE;              

RUN;                                    

 

PROC PRINT   DATA = want; VAR cat_line;

cat_line

A

B

CD

F                                                

 

This data is missing the next value “E”.

 What I wanted and have been trying to get is the data to look like this. AS you can see the E has been added to cat_line.

 

Cat_line

A

B

CDE

F

 

Any thoughts would be greatly appreciated, I have working on this for a while. Thank you!      

1 ACCEPTED SOLUTION

Accepted Solutions
RW9
Diamond | Level 26 RW9
Diamond | Level 26

Please avoid coding all in uppercase, its like your shouting the code at us.  This works:

data rawdata;                      
 input ptr lag_ptr full $5 lead $7;
datalines;                        
0 0 A B                            
0 0 B C                            
5 0 C D                            
5 5 D E                            
0 5 E F                            
0 0 F G                            
;                                  
run;

data want; 
  set rawdata; 
  length cat_line $5;
  retain cat_line;
  if ptr=0 then cat_line=full;                        
  else do;                                
    if lag_ptr=0 then cat_line=cats(full,lead);          
    else cat_line=cats(cat_line,lead);      
  end;
/*  if lag_ptr > 0 then delete;           */   
run; 

Not sure what your intention for the if then delete is, as the row with CDE will be removed by this.

View solution in original post

8 REPLIES 8
mkeintz
PROC Star

Your condition for deletion eliminates the observation you want.

 

As a test, drop the "if ... then delete".  You'll see the observation you want, plus others you don't want.  Then decide what criterion you need to select only the wanted obs.

--------------------------
The hash OUTPUT method will overwrite a SAS data set, but not append. That can be costly. Consider voting for Add a HASH object method which would append a hash object to an existing SAS data set

Would enabling PROC SORT to simultaneously output multiple datasets be useful? Then vote for
Allow PROC SORT to output multiple datasets

--------------------------
a079011
Obsidian | Level 7

Removing the delete statement still does not produce the cat_line I am trying to end up with

cat_line
        
 A      
 B      
 CD     
 E      
 E      
 F      

 

I still need this

A

B

CDE

F

 

thx!

RW9
Diamond | Level 26 RW9
Diamond | Level 26

Please avoid coding all in uppercase, its like your shouting the code at us.  This works:

data rawdata;                      
 input ptr lag_ptr full $5 lead $7;
datalines;                        
0 0 A B                            
0 0 B C                            
5 0 C D                            
5 5 D E                            
0 5 E F                            
0 0 F G                            
;                                  
run;

data want; 
  set rawdata; 
  length cat_line $5;
  retain cat_line;
  if ptr=0 then cat_line=full;                        
  else do;                                
    if lag_ptr=0 then cat_line=cats(full,lead);          
    else cat_line=cats(cat_line,lead);      
  end;
/*  if lag_ptr > 0 then delete;           */   
run; 

Not sure what your intention for the if then delete is, as the row with CDE will be removed by this.

a079011
Obsidian | Level 7

Adding the retain did the trick, as far the delate statement is was looking at backwards. I need to drop the cat_line that does not contain the E. The final result is CDE needed to be concated and just CD is not needed any longer.

 

cat_line
       
 A     
 B     
 CD    
 CDE   
 E     
 F       

a079011
Obsidian | Level 7

"Please avoid coding all in uppercase, its like your shouting the code at us."

 

It is not in all uppercase, key words that are required by SAS are in caps, anything that can change is in lowercase. This is the way I was taught and have always done it that way.

 

Sorry this bothers you.

RW9
Diamond | Level 26 RW9
Diamond | Level 26

Nonsense.  There are no requirements by SAS for anything to be uppercase, only when doing text compares does case make any difference.  Your code is telling other people and the computer the story of your data and processing and should be highly readable by anyone.  

a079011
Obsidian | Level 7

Thank you for your input, I always appreciate other points of view, I don’t recall where I said it was a requirement, because that would be non-sense. Funny thing is 90% of the all the code in my shop is in ALL CAPS, since I am coding on the mainframe is was the default for years. So… code in lower case looks incorrect to me. We can agree to disagree and keep our minds open to the way other people do things.

Thank you again, happy coding.

ballardw
Super User

You need to indicate WHICH E you are expecting in the output.

Since you have any record where lag_ptr > 0 deleted and both of the records in your example data with E as a value have lag_ptr=5 that is a significant issue with getting the state required output.

 

Also since the E appears to be likely from a different row than the one that concatenated C and D you need some sort of RETAIN to keep a value from row to row and an appropriate selection.

 

Perhaps a more verbal description of what this is supposed to be accomplishing might help as well as the entire contents of the output data set.

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
  • 8 replies
  • 888 views
  • 0 likes
  • 4 in conversation