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


>    */

SAS Innovate 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

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