BookmarkSubscribeRSS Feed
Valentin_HU
Calcite | Level 5
Dear all,

I have the following problem:
I use the macro described here: http://www2.sas.com/proceedings/sugi24/Coders/p086-24.pdf.

Code:
%macro replace (dataset = , chkvar = , search = , replace =,
newvar = );
data &dataset (drop = textpos) newvars;
length &newvar $ 200;
set &dataset;
textpos = index(upcase(&chkvar), upcase("&search"));
oldvar = &chkvar;
if textpos ne 0 then
do;
if textpos ne 1 then
&newvar = substr(&chkvar, 1, (textpos - 1)) ||"&replace"||substr(&chkvar, (textpos+length("&search")));
else &newvar = "&replace"||
substr(&chkvar, (textpos + length("&search")));
output newvars;
end;
else &newvar = &chkvar;
output &dataset;
run;
proc print data = newvars;
title “SEARCH FOR ‘&search’ AND REPLACE WITH ‘&replace’”;
var oldvar &newvar;
run;
%mend replace;


This macro replaces a specified string in a cell. The problem is, that it only replaces the first specified string that appears in a cell, when the specified string occurs more than once, the macro does not replace all specified string appearing in the cell but only the first one. How could the macro be fixed in order to replace the specified string as often as the specified string occurs in the cell?

Thanks a lot for your help.

Valentin
4 REPLIES 4
SPR
Quartz | Level 8 SPR
Quartz | Level 8
Hello Valentin,

One of the possible solutions is to loop of this macro making a slight change in its code, namely output testpos as a macro variable, and loop untill testpos=0 like this:
[pre]
%macro replace (dataset = , chkvar = , search = , replace =,
newvar = );
%global tp;
data &dataset (drop = textpos) newvars;
length &newvar $ 200;
set &dataset;
textpos = index(upcase(&chkvar), upcase("&search"));
CALL SYMPUTX('tp',textpos);
oldvar = &chkvar;
if textpos ne 0 then
do;
if textpos ne 1 then
&newvar = substr(&chkvar, 1, (textpos - 1)) ||"&replace"||substr(&chkvar, (textpos+length("&search")));
else &newvar = "&replace"||
substr(&chkvar, (textpos + length("&search")));
output newvars;
end;
else &newvar = &chkvar;
output &dataset;
run;
proc print data = newvars;
title “SEARCH FOR ‘&search’ AND REPLACE WITH ‘&replace’”;
var oldvar &newvar;
run;
%mend replace;
%macro a;
%global tp;
%do %until (&tp = 0);
%replace (dataset = a, chkvar = a, search = dg, replace = yy, newvar =a );
%end;
%mend a;
data a;
a="asdgdfgdg";
b="dg";
run;
%a
[/pre]
Sincerely,
SPR
polingjw
Quartz | Level 8
Maybe I’ve misunderstood your objective, but wouldn’t it be a lot easier to just use the TRANWRD function?
chang_y_chung_hotmail_com
Obsidian | Level 7

Here is one way. hth.

/* test data */
data one;
   old = "asdgdfgdg";
run;

/* create a new var replacing dg with YY in old */
data two;
   set one;
   length new $9;
   new = prxchange("s|dg|YY|", -1, old);
run;

/* check */
proc print data=two;
run;
/* on lst
   Obs   old          new
   1     asdgdfgdg    asYYdfgYY
*/

art297
Opal | Level 21
I like Chang's suggested code and, if you want, it would be simple to wrap it in a macro. E.g., the following uses the same structure (mostly) of the original:
[pre]
%macro replace (dataset = , search = , replace =, variable =, newlength = );
data &dataset. (drop = oldvar);
set &dataset. (rename=(&variable.=oldvar));
length &variable $&newlength.;
&variable. = prxchange("s|&search.|&replace.|", -1, oldvar);
run;
%mend replace;
data have;
informat aetext $50.;
input PTID AETEXT &;
cards;
110 ABD. CRAMPING
160 INTRA-ABD. ABSCESS ABD.
190 (L) ABD. PAIN
220 FOOT ULCER (L) FOOT
230 ABD. PAIN
360 (L) ELBOW CONTUSION
440 PAIN (L) KNEE
520 ACNE
520 TINGLING (L) FOOT
530 ASCITES ABD.
;
run;

%replace (dataset = have,
search = ABD.,
replace = ABDOMINAL,
variable = aetext,
newlength = 50)
[/pre]
HTH,
Art

> Here is one way. hth.

>

>    
> style="color:#008000;font-family:Courier
> New;font-size:10pt;">/* test data */ > pan>

>    
> style="color:#000080;font-family:Courier
> New;font-size:10pt;">data

> style="font-family:Courier
> New;font-size:10pt;"> one;


>      old
>  = 

> style="color:#800080;font-family:Courier
> New;font-size:10pt;">"asdgdfgdg"

> style="font-family:Courier
> New;font-size:10pt;">;


>    
> style="color:#000080;font-family:Courier
> New;font-size:10pt;">run

> style="font-family:Courier
> New;font-size:10pt;">;


>  

>    
> style="color:#008000;font-family:Courier
> New;font-size:10pt;">/* create a new&nb
> sp;var replacing dg with YY i
> n old */


>    
> style="color:#000080;font-family:Courier
> New;font-size:10pt;">data

> style="font-family:Courier
> New;font-size:10pt;"> two;


>       > pan>set
> style="font-family:Courier
> New;font-size:10pt;"> one;


>       > pan>length
> style="font-family:Courier
> New;font-size:10pt;"> new $

> style="color:#008080;font-family:Courier
> New;font-size:10pt;">9

> style="font-family:Courier
> New;font-size:10pt;">;


>      new
>  = prxchange(

> style="color:#800080;font-family:Courier
> New;font-size:10pt;">"s|dg|YY|"

> style="font-family:Courier
> New;font-size:10pt;">, -

> style="color:#008080;font-family:Courier
> New;font-size:10pt;">1

> style="font-family:Courier
> New;font-size:10pt;">, old);


>    
> style="color:#000080;font-family:Courier
> New;font-size:10pt;">run

> style="font-family:Courier
> New;font-size:10pt;">;


>  

>    
> style="color:#008000;font-family:Courier
> New;font-size:10pt;">/* check */


> />
>    
> style="color:#000080;font-family:Courier
> New;font-size:10pt;">proc

> style="font-family:Courier
> New;font-size:10pt;"> 

> style="color:#000080;font-family:Courier
> New;font-size:10pt;">print

> style="font-family:Courier
> New;font-size:10pt;"> 

> style="color:#0000FF;font-family:Courier
> New;font-size:10pt;">data

> style="font-family:Courier
> New;font-size:10pt;">=two;


>    
> style="color:#000080;font-family:Courier
> New;font-size:10pt;">run

> style="font-family:Courier
> New;font-size:10pt;">;


>    
> style="color:#008000;font-family:Courier
> New;font-size:10pt;">/* on lst


> />
>    Obs  
>      old   &nb
> sp;      new


> />
>     1 &n
> bsp;   asdgdfgdg    
> ;asYYdfgYY


>    */

Ready to join fellow brilliant minds for the SAS Hackathon?

Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.

Register today!
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
  • 4 replies
  • 982 views
  • 0 likes
  • 5 in conversation