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?
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
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;
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
Please provide some sample data and desired output.
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
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;
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
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
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
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
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
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
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.