BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
AshJuri
Calcite | Level 5
data subject_data;
input SUBID;
datalines;                                         /*OUTPUT*/

H7891133 1029 10151024               /*H7891133 1015 10151024*/
H7891133 1029 10241005               /*H7891133 1024 10241005*/
H7891133 1029 10241019               /*H7891133 1024 10241019*/
;
run;

%macro mnemonic(in,out);
when ("&in") substr(subid,1,60) = "&out";
%mend;

data update_sub;
set subject_data;
select (substr(subid,1,60));
  %mnemonic(H7891133 1029 10151024 ,H7891133 1015 10151024)
  %mnemonic(H7891133 1029 10241005 ,H7891133 1024 10241005)
  %mnemonic(H7891133 1029 10241019 ,H7891133 1024 10241019)
  otherwise;
end;
run;

Hi, my code currently utilizes a macro to update a column by replacing the middle of a string with a different portion of the string. For example, in "H7891133 1029 10151024", the middle portion "1029" gets replaced by the first four digits of the last portion of the string "1015" so that the updated string is "H7891133 1015 10151024". However, this requires me to list out the subject numbers within the macro. I would like to efficiently update the entire column without having to do any manual listing of the individual subject numbers as there are many records in the dataset. Would concatenation be an option? Any solutions would be appreciated. 

1 ACCEPTED SOLUTION

Accepted Solutions
ballardw
Super User

First thing is to make sure that your data step runs.

This works for your example:

data subject_data;
input SUBID $ 1-22;
datalines;                                         /*OUTPUT*/
H7891133 1029 10151024               /*H7891133 1015 10151024*/
H7891133 1029 10241005               /*H7891133 1024 10241005*/
H7891133 1029 10241019               /*H7891133 1024 10241019*/
;
run;
data want;
  set subject_data;
  subid = tranwrd(subid,'1029',substr(scan(subid,3),1,4));
run;

However I am concerned that this may not be sufficient. Your select is explicitly using a 60 character string but the values you show to manipulate are only 22. So fixed positions in SUBSTR may not be correct.

Another potential issue is if 1029 appears in more than one position in the value such as "H7810293 1029 10241019" or the length of the value to replace changes then the substr range needs to change.

View solution in original post

3 REPLIES 3
Shmuel
Garnet | Level 18

Assuming the substring to be replaced is preceded by a space and followed by a space you don't need a macro, you can use TRANWRD() function.

      variable = tranwrd(variable, "current value", "new_value");

 

ballardw
Super User

First thing is to make sure that your data step runs.

This works for your example:

data subject_data;
input SUBID $ 1-22;
datalines;                                         /*OUTPUT*/
H7891133 1029 10151024               /*H7891133 1015 10151024*/
H7891133 1029 10241005               /*H7891133 1024 10241005*/
H7891133 1029 10241019               /*H7891133 1024 10241019*/
;
run;
data want;
  set subject_data;
  subid = tranwrd(subid,'1029',substr(scan(subid,3),1,4));
run;

However I am concerned that this may not be sufficient. Your select is explicitly using a 60 character string but the values you show to manipulate are only 22. So fixed positions in SUBSTR may not be correct.

Another potential issue is if 1029 appears in more than one position in the value such as "H7810293 1029 10241019" or the length of the value to replace changes then the substr range needs to change.

ErikLund_Jensen
Rhodochrosite | Level 12

Hi @AshJuri 

A small change to the code provided by @ballardw. This doesn't search for the value of the middle string, but changes any value in position 2, so there is no risk of transforming other occurences of the value.

 

data want;
  set subject_data;
  subid = catx(' ',scan(subid,1),substr(scan(subid,3),1,4),scan(subid,3));
run;

SAS Innovate 2025: Call for Content

Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!

Submit your idea!

How to connect to databases in SAS Viya

Need to connect to databases in SAS Viya? SAS’ David Ghan shows you two methods – via SAS/ACCESS LIBNAME and SAS Data Connector SASLIBS – in this video.

Find more tutorials on the SAS Users YouTube channel.

Discussion stats
  • 3 replies
  • 964 views
  • 0 likes
  • 4 in conversation