BookmarkSubscribeRSS Feed
New2SAS_Dee
Calcite | Level 5

I may be expecting too much from SAS on this, but here's the quandary.  I need to have a program that reads instream data, which happens to be strings of characters mixed with numerical values, that also extracts pairs and individual items from the string --- consecutively --- and assigns what it extracts to new variables.

So, for instance, it pulls the first 2 digits and assigns them to a; the 3rd digit is assigned to b; the 4th & 5th are characters assigned to c.... this part is easy  - I got this one.

                    a = input(substr(string,1,2),3.);

                        b = input(substr(string,3,1),3.);

                             c = UPCASE(substr(string,4,2));

This is what's stumping me:

         I'm using an array and do loop to process the 6th through 10th digits into 5 new variables.  Here is the line of code that I'm working on to do this part:

                       array n[5];

                            do i = 1 to 5;

                             n = input(substr(string,6,1),3.);

          *I think I need some more instructions in this spot*

                            end;

So I have the input line there and the pointer starts at positing 6 and pulls only 1 digit -- all that is working -- but my output is wrong because it's populating that 6th digit to all 5 of the new variables.  Obviously this is what I expect to happen right now because I don't know how to tell it to move its pointer to the next digit, process again, then move to the next, and then the next, and so on until it reaches the last digit of the string.  Is this possible?

Thank you.

5 REPLIES 5
Tom
Super User Tom
Super User

What do you mean by INSTREAM data?  Why not just use a normal INPUT statement?

filename mystream temp;

data _null_;

  file mystream ;

  put '123ab67890123ab67890123ab67890123ab67890';

run;

data want ;

  infile mystream recfm=n ; 

  input a 2. b 1. c $2. (n1-n5) (1.) ;

  c=upcase(c);

run;

New2SAS_Dee
Calcite | Level 5

I'm using instream datalines because that's what I have to use (unfortunately).  It's a challenge question and supposedly there's a way to make this happen using an array and do loop.  I hesitate to admit this, but I spent more than 8 hours trying different options and statements to no avail.  It seems like I'm so close and then it gives me the same output.  I've only been working with SAS since January and I'm sure my inexperience with knowing how to word it correctly is part of the problem.  I see your "j+5" in the input statement within the 2nd do loop -- I actually tried something similar to that but it didn't work -- it gave me missing values.  What I tried was not using the J  there but using the 6 because that's the position of the first numerical variable for populating to the new variable n1.  I had the +1 thinking that would move it ahead 1 spot for the next iteration but that didn't work obviously.

New2SAS_Dee
Calcite | Level 5

I am curious as to why you suggested that first array at the top.  Is that more efficient for SAS to process?  BTW, here's what I ended up with  -- certainly not as compact and efficient as I originally intended and yours looks so much more impressive.  This is the entire code with the final variables being used (which is why they aren't a,b,c).  Thank you for your time and advice.  As a novice, I can only imagine the knowledge and experience you all have amassed over time.  You've been very helpful.

Tom
Super User Tom
Super User

If you are using an INPUT statement then you do not need to mess with trying to pick the values out of a string variable.  You can read the line into a string variable also if you want.

I wouldn't mess with setting length of numeric variables less than 8 unless you have zillions of records.  SAS stores all numbers as floating point.

data want ;

  infile cards truncover ;

   input a 2. b 1. c $2. (n1-n5) (1.) @1 string $10. ;

c=upcase(c);

cards;

123ab67890

123ab67890

123ab67890

123ab67890

;;;;

Tom
Super User Tom
Super User

Why not just introduce another loop?

data want ;

  string='123ab67890123ab67890123ab67890123ab67890';

  do i=1 by 10 while (i < length(string)) ;

    substring=substr(string,i,10);

    a=input(substring,2.);

    b=input(substr(substring,3),1.);

    c=upcase(substr(substring,4,2));

    do j=1 to 5 ;

      array n(5) ;

      n(j) = input(substr(substring,j+5),1.);

    end;

    output;

  end;

  drop i j substring ;

run;

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!

What is Bayesian Analysis?

Learn the difference between classical and Bayesian statistical approaches and see a few PROC examples to perform Bayesian analysis in this video.

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
  • 791 views
  • 4 likes
  • 2 in conversation