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-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!

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
  • 10 replies
  • 4006 views
  • 3 likes
  • 4 in conversation