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

Hi all,

 

I'm trying to transpose this set using version 9.4 so before and after are column headers and the datalines fall below it.

 

Before 300 350 190 400 244 321 330 250 190 160 260 240
After 290 331 200 395 240 300 332 242 185 158 256 220

 

Every method I have tried thus far hasn't been successful. With the version of the code I've been currently using I get the error "Array subscript out of range at line ___"

 

What the heck am I missing? My current version of the code is below.

 

DATA dietpair (keep = before after);
infile 'X:\SASDATA\cody_chap06_num06.dat';
input trt $ 1-6 subject1-subject12;
array weight (12) subject1-subject12;
do i = 1-12;
if trt = 'Before' then before = weight(i);
else if trt = 'After' then after = weight(i);
end;
RUN;

1 ACCEPTED SOLUTION

Accepted Solutions
Tom
Super User Tom
Super User

Since the data is rotated you might need to read it into two arrays if you want to transpose it in one pass.

data want;
   input label1 $ x1-x12 / label2 $ y1-y12 ;
   array x [12];
   array y [12];
   do subject=1 to 12 ;
       if label1 = 'Before' and label2='After' then do;
          before=x[subject]; after=y[subject];
      end;
       else if label2 = 'Before' and label1='After' then do;
          before=y[subject]; after=x[subject];
      end;
      else do;
          put 'Invalid row labels. ' label1= label2= ;
          stop;
      end;
      output;
   end;
   keep subject before after ;
cards;
Before 300 350 190 400 244 321 330 250 190 160 260 240
After 290 331 200 395 240 300 332 242 185 158 256 220
;

View solution in original post

7 REPLIES 7
Tom
Super User Tom
Super User

Negative eleven is not going to be a valid index into your array.   You need use integers from 1 to 12 instead.

do I=1 to 12;

Do you only want the value for subject 12?  Or do you want to output all of them?  You need an OUTPUT statement inside your DO loop.

 

data dietpair ;
  infile 'X:\SASDATA\cody_chap06_num06.dat';
  input trt $ 1-6 @ ;
  do subject=1 to 12;
     input weight @;
     output;
  end;
run;

proc sort; by subject trt; run;

bonedog
Fluorite | Level 6

I don't know where you're seeing negative 11  - this is already what I have in my code.

 

Screen Shot 2019-07-22 at 4.25.01 PM.png

Tom
Super User Tom
Super User

one minus twelve is negative eleven.

ballardw
Super User

@bonedog wrote:

I don't know where you're seeing negative 11  - this is already what I have in my code.

 

Screen Shot 2019-07-22 at 4.25.01 PM.png


Iterated do loops are

 

do I = <startvalue> to <endvalue> <optionally> by byvalue;

Startvalue, endvalue and byvalue can be 1) literal values, 1 or 12, 2) variable names or 3) expressions that resolve to integers though the values and sign of byvalue need to matched carefully. Note the word is to, not a dash.

bonedog
Fluorite | Level 6

Tom,

 

Thanks for pointing out my error there. The fix has gotten me most of the way there.

 

This is my current code:

DATA dietpair (keep = before after);
	infile 'X:\SASDATA\cody_chap06_num06.dat';
	input trt $ 1-6 subject1-subject12;
	array weight (12) subject1-subject12;
	do i = 1 to 12;
	if trt = 'Before' then before = weight(i);
	else if trt = 'After' then after = weight(i);
	output;
	end;
RUN;

And this is the output I'm getting. 

                             Obs    before    after

                               1      300        .
                               2      350        .
                               3      190        .
                               4      400        .
                               5      244        .
                               6      321        .
                               7      330        .
                               8      250        .
                               9      190        .
                              10      160        .
                              11      260        .
                              12      240        .
                              13        .      290
                              14        .      331
                              15        .      200
                              16        .      395
                              17        .      240
                              18        .      300
                              19        .      332
                              20        .      242
                              21        .      185
                              22        .      158
                              23        .      256
                              24        .      220


How can I make it so I only have 12 observations where the before and after values line up?

novinosrin
Tourmaline | Level 20

Hello @bonedog   Do you just have two records in your source data?

Tom
Super User Tom
Super User

Since the data is rotated you might need to read it into two arrays if you want to transpose it in one pass.

data want;
   input label1 $ x1-x12 / label2 $ y1-y12 ;
   array x [12];
   array y [12];
   do subject=1 to 12 ;
       if label1 = 'Before' and label2='After' then do;
          before=x[subject]; after=y[subject];
      end;
       else if label2 = 'Before' and label1='After' then do;
          before=y[subject]; after=x[subject];
      end;
      else do;
          put 'Invalid row labels. ' label1= label2= ;
          stop;
      end;
      output;
   end;
   keep subject before after ;
cards;
Before 300 350 190 400 244 321 330 250 190 160 260 240
After 290 331 200 395 240 300 332 242 185 158 256 220
;

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

Register now!

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
  • 7 replies
  • 1389 views
  • 4 likes
  • 4 in conversation