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