BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
stataq
Quartz | Level 8

Hello,

 

I would like to find a way to subtract the punctuation out of string into multiple marco variables. 

 

For example: 

invalue="X/X(X%)"

I would like to use 'X' as delimiter to find any sign before or after 'X' and then store them into a serial of marco variables with prefix _s. So here I would like to build following macro variables:

_s1=

_s2=/

_s3=(

_s4=%)

 

If invalue="(x-x)" then the set I want will be

_s1=(

_s2=-

_s3=)

 

How can I achieve this goal? As invalue format is not the same, the punctuation position will change case by case.  

 

Thanks.

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
Quentin
Super User

Paige is asking the right questions.  This is an odd thing to want to do.  Are you reading in a table shell as data?  That seems like a reasonable thing to do, and parsing the data to get the mathematical symbols is not a crazy idea, but storing the results in macro variables is probably not the best approach, depending on the big picture.

 

That said, you can do it in a DATA step, using COUNTW to find the number of works, and using SCAN to find each word.  Then CALL SYMPUTX to create a macro variable for each word. Something like:

 

data _null_ ;
  invalue="X/X(X%)" ;
  do i=1 to countw(invalue,"X","mi") ;
    call symputx(cats("_s",i),scan(invalue,i,"X","mi")) ;
  end ;
run ;

%put _user_ ;

Typically I would want to keep this data in a data set, instead of storing it in macro variable, so I might do it like:

data want ;
  invalue="X/X(X%)" ;
  length symbol $8 ;
  do i=1 to countw(invalue,"X","mi") ;
    symbol=scan(invalue,i,"X","mi") ;
    output ;
  end ;
run ;

proc print data=want ;
run ;
The Boston Area SAS Users Group (BASUG) is hosting our in person SAS Blowout on Oct 18!
This full-day event in Cambridge, Mass features four presenters from SAS, presenting on a range of SAS 9 programming topics. Pre-registration by Oct 15 is required.
Full details and registration info at https://www.basug.org/events.

View solution in original post

5 REPLIES 5
PaigeMiller
Diamond | Level 26

This strikes me as a problem that is made extra difficult by using macro variables. A simplification would be to do this in a DATA step using either PRX or SCAN functions in the data step.

 

This also strikes me as a problem that could be simplified even further, if only we knew exactly why the data is arranged this way, and what you intend to do with it after you perform these string manipulations. So, @stataq, please explain the big picture: why is the data arranged this way in the first place, and what will you do with these strings once you obtain them.

--
Paige Miller
stataq
Quartz | Level 8
@PaigeMiller I was thinking to get all punctuations out and later substitute X with other values to build a new string.

PaigeMiller
Diamond | Level 26

I don't think you answered my questions. Please take a step back and provide the big picture, rather than tightly focusing on this exact piece of code that you want help with.

 

Why is the data arranged this way?

 

What will you with these character strings after you have code that extracts there character strings?

--
Paige Miller
ballardw
Super User

@stataq wrote:
@PaigeMiller I was thinking to get all punctuations out and later substitute X with other values to build a new string.


Then the order is wrong. You want what you are calling X to become macro variables, in place, and then substitute the X for macro variable references.

 

/* orginal value is
   a / b .. c
*/

%let x1=ABC;
%let x2=PDQ;
%let x3=XYZ;

%let macrostr= &x1 / &x2 .. &x3;

%put the value of macrostr is: &macrostr.;

Though still sounds moderately awkward at best without a real use case or two.

Quentin
Super User

Paige is asking the right questions.  This is an odd thing to want to do.  Are you reading in a table shell as data?  That seems like a reasonable thing to do, and parsing the data to get the mathematical symbols is not a crazy idea, but storing the results in macro variables is probably not the best approach, depending on the big picture.

 

That said, you can do it in a DATA step, using COUNTW to find the number of works, and using SCAN to find each word.  Then CALL SYMPUTX to create a macro variable for each word. Something like:

 

data _null_ ;
  invalue="X/X(X%)" ;
  do i=1 to countw(invalue,"X","mi") ;
    call symputx(cats("_s",i),scan(invalue,i,"X","mi")) ;
  end ;
run ;

%put _user_ ;

Typically I would want to keep this data in a data set, instead of storing it in macro variable, so I might do it like:

data want ;
  invalue="X/X(X%)" ;
  length symbol $8 ;
  do i=1 to countw(invalue,"X","mi") ;
    symbol=scan(invalue,i,"X","mi") ;
    output ;
  end ;
run ;

proc print data=want ;
run ;
The Boston Area SAS Users Group (BASUG) is hosting our in person SAS Blowout on Oct 18!
This full-day event in Cambridge, Mass features four presenters from SAS, presenting on a range of SAS 9 programming topics. Pre-registration by Oct 15 is required.
Full details and registration info at https://www.basug.org/events.

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