BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
soomx
Fluorite | Level 6

Example:

Let's say I have observations with a variable string as such (it differs across observations):

Person A) .   ------XXX------XXXXXXXXXXXXXXXXXXXXX-------

Person B) .   ------XXXXXXXXXXXXXXXXXXXXXXXXX-------

Person C) .   ------XXX---XXXXXXXXXX----XXXXXXXXXXXXXXXXXXXX-------

 

I have the position number of the red X and have defined this position number as POS.

How do I use POS to find the position of the blue X?

 

Thank you! 

1 ACCEPTED SOLUTION

Accepted Solutions
Astounding
PROC Star

This might be brutal and inelegant, but it should work:

 

data want;

set have;

if POS > 1 then do k=POS-1 to 1 by -1 until (substr(string, k, 1) ne "X");

end;

first_x = k + 1;

run;

View solution in original post

6 REPLIES 6
Reeza
Super User

So you're looking for the start of the substring?

 

Do you have the delimiters shown, the ---? If so, I would consider modifying this a bit to use the SCAN() or you could just loop through and check each character until you find the first - and then use that. 

 

You need to confirm the structure of your data first though. 

 


@soomx wrote:

Example:

Let's say I have observations with a variable string as such (it differs across observations):

Person A) .   ------XXX------XXXXXXXXXXXXXXXXXXXXX-------

Person B) .   ------XXXXXXXXXXXXXXXXXXXXXXXXX-------

Person C) .   ------XXX---XXXXXXXXXX----XXXXXXXXXXXXXXXXXXXX-------

 

I have the position number of the red X and have defined this position number as POS.

How do I use POS to find the position of the blue X?

 

Thank you! 


 

 

ChrisNZ
Tourmaline | Level 20

Like this?

data HAVE;
  A='------123-----Aabcdefghijklmnopqrsx--------'; POS=25; output;
  A='----BXXXXXXXXXXXXXXXXXXXXXXXX-------       '; POS=20; output;
  A='----XXX---XXXXXXXXXX----CXXXXXXXXXXXXXXXX--'; POS=40; output;
run;
data WANT;
  set HAVE;          
  POS2=findc(reverse(A),'-',length(A)-POS)-1;
  B=char(reverse(A),POS2); 
run;
A POS POS2 B
------123-----Aabcdefghijklmnopqrsx-------- 25 29 A
----BXXXXXXXXXXXXXXXXXXXXXXXX------- 20 39 B
----XXX---XXXXXXXXXX----CXXXXXXXXXXXXXXXX-- 40 19 C

 

 

Cynthia_sas
SAS Super FREQ
Hi:
Are your variable strings always separated by --- as you show, or is that just fake filler that you added? It appears that the blue X is a different number of positions away from the red X? Is that correct? Or did you mis-count and the blue X and red X are always 17 or 18 positions apart? How did you get the position of the red X into a variable named POS?

What code have you tried? What functions have you tried. The answer will be different whether your strings are separated by ---- or not.

Cynthia
Astounding
PROC Star

This might be brutal and inelegant, but it should work:

 

data want;

set have;

if POS > 1 then do k=POS-1 to 1 by -1 until (substr(string, k, 1) ne "X");

end;

first_x = k + 1;

run;

soomx
Fluorite | Level 6

Thank you! This worked perfectly. 

 

To answer the other questions (apologies for not being more clear):

The variable string have values of dashes and Xs (i.e. the dashes are not fake fillers). Observations have differing lengths and patterns of Xs and dashes. These dashes and Xs represent presence at a specific visit/time point (akin to yes/no present), and the position of each character represents which time point. I have the variable POS to indicate the position of the red X because that is my time point of interest. I wanted to find the position of the blue X to find the starting point in which observations had continuous presence at each visit until the visit of interest. Hopefully that is more clear.

 

s_lassen
Meteorite | Level 14

I would use CALL SCAN:

data have;
  input key $10. string $50.;
cards;
Person A) ------XXX------XXXXXXXXXXXXXXXXXXyXX-------
Person B) ------XXXXXXXXXXXXXXXXXXXXXXyXX-------
Person C) ------XXX---XXXXXXXXXX----XXXXXXXXXXXXXXXXXyXX-------
;run;

data want;
  set have;
  pos=index(string,'y');
  do _N_=1 by 1 until(pos2<pos<pos2+len or pos2=0);
    call scan(string,_N_,pos2,len,'-');
    end;
  drop len;
run;

The position of the first letter in the word containing the letter "y" (a substitute for the red "X") should then be in the variable pos2.

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
  • 6 replies
  • 7296 views
  • 0 likes
  • 6 in conversation