03-27-2015 07:36 PM
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:
do i = 1 to 5;
n = input(substr(string,6,1),3.);
*I think I need some more instructions in this spot*
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?
03-28-2015 12:12 PM
What do you mean by INSTREAM data? Why not just use a normal INPUT statement?
filename mystream temp;
file mystream ;
data want ;
infile mystream recfm=n ;
input a 2. b 1. c $2. (n1-n5) (1.) ;
03-28-2015 03:00 PM
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.
03-28-2015 03:09 PM
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.
03-30-2015 09:16 AM
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. ;
03-28-2015 12:28 PM
Why not just introduce another loop?
data want ;
do i=1 by 10 while (i < length(string)) ;
do j=1 to 5 ;
array n(5) ;
n(j) = input(substr(substring,j+5),1.);
drop i j substring ;