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


I'd like to calculate the mean and standard deviation of each row in an array.  Something like

array pvbp(&scenarios,n);

... [populate array]

array mx(n); array sx(n);

do i = 1 to n;

     mx(n) = mean(of pvbp(*,n));

     sx(n) = std(of pvbp(*,n));

end;

The code above doesn't work - it gives a syntax error.  Is there a simple fix?

1 ACCEPTED SOLUTION

Accepted Solutions
KachiM
Rhodochrosite | Level 12

Function to find mean and STD for partial array ie for a 2-dimensional array is not provided by SAS as far as I know. Instead compute the mean and std by adding some more steps as;

data _null_;

set have;

array s(5,2);

do i = 1 to 5;

     do j = 1 to 2;

          s(i,j) = age + i + j;

     end;

end;

array mx(2);

array sx(2);

do k = 1 to 2;

   do i = 1 to dim1(s);

      X + s[i, k];

      XX + (s[i,k] * s[i,k]);

   end;

     mx(k) = X / dim1(s);

     sx(k) = (XX - X * X / dim1(s)) / (dim1(s) - 1);

     put mx = ;

     put sx = ;

end;

stop;

run;

Correction: Take square root of SX for STD.

View solution in original post

10 REPLIES 10
stat_sas
Ammonite | Level 13

Not sure about the error you are getting. Something like this will produce mean and standard deviation for each row

data have;
input p1-p7;
cards;
1 2 3 2 2 3 2
2 3 4 2 3 2 3
3 3 4 3 5 2 4
4 3 4 5 2 2 2
;

run;
data want;
set have;
array p(*) p1-p7;
do i=1 to dim(p);
mean=mean(of p(*));
std=std(of p(*));
end;
run;

mcs
Obsidian | Level 7 mcs
Obsidian | Level 7

Thanks for the reply.

Using mean(of p(*)) and ste(of p(*)) would work if i wanted to calculate statistics for a one-dimensional matrix for each row of a data set.

Instead, I want to calculate multiple statistics from a two-dimensional array, i.e., mean(of p(*,1)) to mean(of p(*,n)), etc., for each row of a data set.

Martin

stat_sas
Ammonite | Level 13

Please provide some sample data and desired output.

mcs
Obsidian | Level 7 mcs
Obsidian | Level 7

data have;

input sex $ age;

cards;

M 45

F 50

U 60

;

data mc;

set have;

array s(5,2);

do i = 1 to 5;

     do j = 1 to 2;

          s(i,j) = age + i + j;

     end;

end;

array mx(2);

array sx(2);

do k = 1 to 2;

     mx(k) = mean(of s(*,k));

     sx(k) = std(of s(*,k);

end;

run;

Desired output:

_N_ = 1

     mx1 = mean(of (47,48,48,49,49)) = 48.2, similary for mx2

     sx1 = std(of (47,48,48,49,49)) = 0.84, similary for sx2

_N_ = 2

     mx1 = mean(of (52,53,53,54,54)) = 53.2, similary for mx2

     sx1 = std(of (52,53,53,54,54)) = 0.84, similarly for sx2

_N_ = 3

     etc.

Instead I get the following syntax error.

21     mx(k) = mean(of (s(*,k));

                                          -

                                          22

                                          76

ERROR 22-322: Syntax error, expecting one of the following: ), ], }.

Martin

stat_sas
Ammonite | Level 13

data mc;

set have;

array s(5,2);

do i = 1 to 5;

     do j = 1 to 2;

          s(i,j) = age + i + j;

     end;

end;

array mx(2);

array sx(2);

array sv{*} s1-s10;

do k = 1 to 2;

    if k=1 then do;

     mx(k)=mean(of s1-s5);

     sx(k)=std(of s1-s5);

  end;

     if k=2 then do;

     mx(k)=mean(of s6-s10);

     sx(k)=std(of s6-s10);

  end;

end;

run;

mcs
Obsidian | Level 7 mcs
Obsidian | Level 7

Thanks for the reply.

This works, but the range of k is, say, 1 to 100 instead of 1 to 2, it involves a lot of repeated code.

Martin

Ksharp
Super User

Are you trying to use SAS/IML or not ?

one way in data step is to create a temporary array x{*} to hold these whole row and use  mean(of x{*}) .

Xia Keshan

mcs
Obsidian | Level 7 mcs
Obsidian | Level 7

Thanks for the reply.

I'm using Base SAS, not SAS/IML

If I use temporary arrays xn(*) for each of x(*,n), I'll need n of them.  I'd prefer to avoid n lines of repeated code.  Is there a simple way to create an array of arrays to loop over?  I imagine I could do it with macros, but I have less experience working with those.

Martin

KachiM
Rhodochrosite | Level 12

Function to find mean and STD for partial array ie for a 2-dimensional array is not provided by SAS as far as I know. Instead compute the mean and std by adding some more steps as;

data _null_;

set have;

array s(5,2);

do i = 1 to 5;

     do j = 1 to 2;

          s(i,j) = age + i + j;

     end;

end;

array mx(2);

array sx(2);

do k = 1 to 2;

   do i = 1 to dim1(s);

      X + s[i, k];

      XX + (s[i,k] * s[i,k]);

   end;

     mx(k) = X / dim1(s);

     sx(k) = (XX - X * X / dim1(s)) / (dim1(s) - 1);

     put mx = ;

     put sx = ;

end;

stop;

run;

Correction: Take square root of SX for STD.

mcs
Obsidian | Level 7 mcs
Obsidian | Level 7

Thanks.  That looks like it should work even when the bounds on s and k are large.

I think a slight improvement would be to calculate the running variance as shown at http://www.johndcook.com/standard_deviation.html

Initialize M1 = x1 and S1 = 0.

For subsequent x's, use the recurrence formulas

Mk = Mk-1+ (xk - Mk-1)/k

Sk = Sk-1 + (xk - Mk-1)*(xk - Mk).

For 2 ≤ k ≤ n, the kth estimate of the variance is s2 = Sk/(k - 1).

Martin

sas-innovate-wordmark-2025-midnight.png

Register Today!

Join us for SAS Innovate 2025, our biggest and most exciting global event of the year, in Orlando, FL, from May 6-9. Sign up by March 14 for just $795.


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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 10 replies
  • 5045 views
  • 3 likes
  • 4 in conversation