Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

use a do loop inside an infile data step

Tags:

sas

I want to import a text dataset that looks like this:

Abc1defxx
Ghi2klmaabb
nop1qrscc
tuv3wxyccbbzz
…

Here is the table I want:

text    n_names info    name_1  name_2  name_3
Abc     1       def     xx        
Ghi     2       klm     aa      bb    
nop     1       qrs     cc        
tuv     3       wxy     cc      bb      zz 
…                   

As you notice the length is not constant, and I need the information from n_names to determine how many variables names I want. what I did here is:

data Dta;
    %let _EFIERR_ = 0; /* set the ERROR detection macro variable */
    infile "\\mypath\import.txt"
        truncover;
    input
        text $ 1 - 3 
        n_names 4 
        info $ 5 
        info1 $ 6-7@;

    do j=0 to n_names;
        %let pos= 7 + &j*2;

        if &j < nrum then
            input @&pos name_&j  $2. @;
        else input @&pos name_&j  $2.;
    end;
run;

I have the impression the loop doesn't go on and j and n_names are not taking a numerical value, because even when I manage to get an output dataset, it only has name_0 column.

Is the loop supposed to work after infile? I don't see why it shouldn't.

like image 545
DURAL Avatar asked Apr 09 '26 07:04

DURAL


1 Answers

Basically, what you're doing here is reading in the n_names and holding the input pointer, and then continuing to read in the rest. Here's a datalines example. This requires knowing the maximum N_NAMES (which you can find out if you want to programatically):

data want;
input
@1 text $3.
@4 n_names 1. 
@5 info $1.
@6 info1 $2. @; *trailing @ says 'wait for more';

array names $ names_1-names_15; *set _15 to whatever the maximum is;
_i=1;
do _pos = 8 to (6+2*n_names) by 2;
 input @_pos names[_i] $2. @;
 _i=_i+1;
end;
datalines;
Abc1defxx
Ghi2klmaabb
nop1qrscc
tuv3wxyccbbzz
;;;;
run;

You also could use array input, if you don't have anything else after this and again either know your maximum NAME_# or are okay with guessing something high (you can programatically figure it out if needed). Here's a datalines example. If you use a real file, you should use TRUNCOVER or MISSOVER to ensure it doesn't continue to the next row.

data want;
array names $ names_1-names_15 ;
input
@1 text $3.
@4 n_names 1. 
@5 info $1.
@6 info1 $2.
@8 names[*] $2.
;
datalines;
Abc1defxx
Ghi2klmaabb
nop1qrscc
tuv3wxyccbbzz
;;;;
run;
like image 167
Joe Avatar answered Apr 12 '26 17:04

Joe