SAS Programming

DATA Step, Macro, Functions and more
BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
Pili1100
Obsidian | Level 7

Hi, 

I would like to replace a generic part of a string and replace with value from one variable in another variable. 

Pili1100_0-1668792504941.png

 





/*input*/
DATA input;
LENGTH LIB_TABLES $100;
INPUT LIB_TABLES;
DATALINES;
LIB_A.TABLE_1
LIB_B.TABLE_2
LIB_C.TABLE_3
;

RUN;

/*What I have*/
DATA have;
SET input;
LIB = SCAN( LIB_TABLES, 1, '.');
TABLES = REVERSE(SCAN(REVERSE(LIB_TABLES),1,'.'));
X_have= 'info_tables(LIBNAME=XXX, TABLE=XXX, Table info)';

RUN;



/*Desirable output*/
DATA want; 

LIB_TABLES = 'LIB_A.TABLE_1';
LIB		   = 'LIB_A';
TABLES	   = 'TABLE_1';
X_WANT	   = 'info_tables(LIBNAME=LIB_A,TABLE=TABLE_1, Table info)';
OUTPUT;

	
LIB_TABLES = 'LIB_B.TABLE_2';
LIB		   = 'LIB_B';
TABLES	   = 'TABLE_2';
X_WANT	   = 'info_tables(LIBNAME=LIB_B,TABLE=TABLE_2, Table info)';
OUTPUT;


LIB_TABLES = 'LIB_C.TABLE_3';
LIB		   = 'LIB_C';
TABLES	   = 'TABLE_3';
X_WANT	   = 'info_tables(LIBNAME=LIB_C,TABLE=TABLE_3, Table info)';
OUTPUT;
RUN;	




How should I do it?

Many thanks, 

 

1 ACCEPTED SOLUTION

Accepted Solutions
fja
Lapis Lazuli | Level 10 fja
Lapis Lazuli | Level 10

As you stated that you wanted to _replace_ a certain char group by a variable my suggestion would be using the tranwrd function . ... note the trim(). This was suggested by @Tom in this post

/*input*/ 
DATA input; 
LENGTH LIB_TABLES $100; 
INPUT LIB_TABLES; 
DATALINES; 
LIB_A.TABLE_1 
LIB_B.TABLE_2 
LIB_C.TABLE_3 
; 
RUN; 
 
/*What I have*/ 
DATA have; 
SET input; 
LIB = SCAN( LIB_TABLES, 1, '.'); 
TABLES = REVERSE(SCAN(REVERSE(LIB_TABLES),1,'.')); 
X_have= 'info_tables(LIBNAME=XXX, TABLE=YYY, Table info)'; 
x_want=tranwrd(tranwrd(x_have, "YYY", trim(TABLES)), "XXX", trim(LIB)); 
RUN; 
proc print data=have;

 

fja_0-1668803351806.png

 

View solution in original post

8 REPLIES 8
Cynthia_sas
SAS Super FREQ

Hi:

  You are very close. Using one of the concatenate functions to join your text and your variable values will work. I'd recommend the CATT function, which trims blanks:

Cynthia_sas_0-1668802112714.png

I also simplified your SCAN, since using a -1 tells SCAN to start scanning from the other end of the variable string, which is what your REVERSES were doing.

Cynthia

fja
Lapis Lazuli | Level 10 fja
Lapis Lazuli | Level 10

As you stated that you wanted to _replace_ a certain char group by a variable my suggestion would be using the tranwrd function . ... note the trim(). This was suggested by @Tom in this post

/*input*/ 
DATA input; 
LENGTH LIB_TABLES $100; 
INPUT LIB_TABLES; 
DATALINES; 
LIB_A.TABLE_1 
LIB_B.TABLE_2 
LIB_C.TABLE_3 
; 
RUN; 
 
/*What I have*/ 
DATA have; 
SET input; 
LIB = SCAN( LIB_TABLES, 1, '.'); 
TABLES = REVERSE(SCAN(REVERSE(LIB_TABLES),1,'.')); 
X_have= 'info_tables(LIBNAME=XXX, TABLE=YYY, Table info)'; 
x_want=tranwrd(tranwrd(x_have, "YYY", trim(TABLES)), "XXX", trim(LIB)); 
RUN; 
proc print data=have;

 

fja_0-1668803351806.png

 

Pili1100
Obsidian | Level 7

Thank you for the double-trim. Will come in handy for replacing in a string 😁

Pili1100
Obsidian | Level 7

Hi,

I got so many good solutions from the community. Thank you for helping me. This one works as charm! 🙏

Tom
Super User Tom
Super User

To re-create your example does NOT require replacing any text.

Just GENERATE the text.

DATA input;
  LENGTH LIB_TABLES $100;
  INPUT LIB_TABLES;
DATALINES;
LIB_A.TABLE_1
LIB_B.TABLE_2
LIB_C.TABLE_3
;

data want;
  set input;
  length lib $8 tables $32 x_want $100 ;
  lib=scan(lib_tables,1,'.');
  tables=scan(lib_tables,-1,'.');
  x_want=cats('info_tables(libname=',lib,',table=',tables,',Table info)');
run;

Result

Obs     LIB_TABLES       lib     tables                           x_want

 1     LIB_A.TABLE_1    LIB_A    TABLE_1    info_tables(libname=LIB_A,table=TABLE_1,Table info)
 2     LIB_B.TABLE_2    LIB_B    TABLE_2    info_tables(libname=LIB_B,table=TABLE_2,Table info)
 3     LIB_C.TABLE_3    LIB_C    TABLE_3    info_tables(libname=LIB_C,table=TABLE_3,Table info)

Do you have an example where you actually need to replace text?

Pili1100
Obsidian | Level 7

Thank you for helping me. Another good solution. 😊
Regarding your question, Do you have an example where you actually need to replace text? and the 
reason I need help with this because I was looking for a solution for a makro where I use lib and tables and I wanted to avoid to copy/pase the XXX. 

It can be time consuming when it's 20 tables.  

Patrick
Opal | Level 21

Pretty much the same as Tom already suggested with the one extension to also deal with one level table names.

DATA have;
  LENGTH LIB_TABLES $100;
  INPUT LIB_TABLES;
  DATALINES;
LIB_A.TABLE_1
LIB_B.TABLE_2
LIB_C.TABLE_3
TABLE4
;

data want;
  set have;
  length lib $8 tables $32 x_want $100;
  lib=scan(cats('WORK.',lib_tables),-2,'.');
  tables=scan(lib_tables,-1,'.');
  x_want=cats('info_tables(LIBNAME=',lib,', table=',tables,', Table info)');
run;

 

Patrick_0-1668807737714.png

 

Pili1100
Obsidian | Level 7

Hi, 

Thanks for expanding the solution, having WORK as default. Real nice 👏

 

sas-innovate-white.png

Special offer for SAS Communities members

Save $250 on SAS Innovate and get a free advance copy of the new SAS For Dummies book! Use the code "SASforDummies" to register. Don't miss out, May 6-9, in Orlando, Florida.

 

View the full agenda.

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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 8 replies
  • 5290 views
  • 0 likes
  • 5 in conversation