SAS 中的 ARRAY 函数在 MEAN 之后(通过分组)
ARRAY function in SAS after MEAN (by grouping)
SAS 有一些作业,但我似乎找不到正确的方法。希望你们中的一些人能够提供帮助。
我们从一个 table 开始,其中我们有以下变量:
City State Temp January Temp Feb Temp Mar ... Temp Dec
首先,我们必须计算平均温度(每月,因此对于 12 个不同的变量)和每个州(因此每个州总是有几个城市)。
我使用了这个代码:
PROC SORT DATA=Homework;
BY state;
RUN;
PROC MEANS DATA=Homework;
VAR JAN FEB MAR APR MAY JUN JUL AUG SEP OCT NOV DEC;
BY State
OUTPUT OUT=MTSM (DROP=_type_ _freq_) MEAN=;
RUN;
我的结果是 table,其中我有 53 行(每个州一行)和每月 1 列(第一列用于各州)。像这样:
State JAN FEB ... DEC
State1 xjan xfeb ... xdec
State2
...
State53
现在我需要使用 Array statement
以长格式制作新的 table:
State Month Mean_temp
State1 JAN xjan
state1 FEB xfeb
. MAR ...
. APR ...
. ... ...
State1 DEC xdec
State 2 JAN ...
...
DEC
...
State53 JAN
FEB
...
有人知道如何做到这一点吗?我完全迷路了。
这是我试过的:
DATA MTSM2;
SET MTSM;
BY state;
ARRAY newvars {1} Mean_Temp;
ARRAY oldvars {1, 12} JAN FEB MAR APR MAY JUN JUL AUG SEP OCT NOV DEC;
DO Month = JAN to DEC;
DO k=1;
newvars{k} = oldvars{k, Month};
END;
OUTPUT;
END;
KEEP state Month Mean_Temp;
RUN;
我收到以下错误:ERROR: Array subscript out of range at line 30 column 22
:'(
我做错了什么?我一直在以多种方式更改它,但总是得到相同的错误。
提前致谢!
听起来您只是想使用 Class 语句而不是 By 语句?
您可以通过在 proc means
/proc summary
:
中使用更具体的 output
语句来获得您想要的 table
/*Generate some dummy data*/
data have;
call streaminit(1);
do j = 1 to 10;
do state = 'a', 'b', 'c';
array months[12] m1-m12;
do i = 1 to dim(months);
months[i] = rand('uniform');
end;
output;
end;
end;
drop i j;
run;
proc summary nway data = have;
var m1-m12;
class state;
output out = want(drop = _TYPE_ _FREQ_) mean=;
run;
如果作业是旋转数据,使用 ARRAY
,从分类组织布局 (state
/month
/mean
) 到宽布局 ( state
/month-1
...month-12
)可以用BY
处理和index
判断来填充一个数组。
基本上每个 BY
组将有一行输出。
一种方法是使用 DOW 循环,其中 SET
语句位于显式循环内。
data want(keep=state jan--dec);
do until (last.state);
set have;
by state;
array months jan feb mar apr may jun jul aug sep oct nov dec;
index = (index('JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC', trim(month))+2)/3;
months(index) = mean;
end;
run;
如果已知数据每个月都有,则不需要索引'lookup',直接从do循环索引变量中获取:
data want(keep=state jan--dec);
do _n_ = 1 by 1 until (last.state); /* repurpose _n_ */
set have;
by state;
array months jan feb mar apr may jun jul aug sep oct nov dec;
months(_n_) = mean;
end;
run;
更新
使用 array
将数据从 across 布局旋转到 down 布局。在数组元素和循环内的 output
name/value 对上迭代一个循环。
data want (keep=state month percent);
set have;
array months jan feb mar apr may jun jul aug sep oct nov dec;
do _n_ = 1 to dim(months);
month = vname(months(_n_)); /* name */
percent = months(_n_); /* value */
OUTPUT;
end;
run;
Proc TRANSPOSE
可以进行相同的数据转换。
当您想同时转置两个或多个数组时,基于数组的旋转非常有用。一个例子是如果你有变量
jan_percent
到 dec_percent
和
jan_rating
到 dec_rating
您想转换成 month
/percent
/rating
的数据形式。 TRANSPOSE
的这种转换需要多个 proc 步骤(每个数组一个)。
你们很亲近。
没有必要为新变量使用 ARRAY,因为它只是一个。列出实际变量名称后,无需告诉 SAS 数组中有多少个变量。并且数组由整数而不是字符串索引。您可以使用 VNAME()
函数在数组中查找由索引寻址的变量的名称。不需要 BY 语句。
DATA MTSM2;
SET MTSM;
ARRAY oldvars JAN FEB MAR APR MAY JUN JUL AUG SEP OCT NOV DEC;
length month mean_temp 8;
DO month_number = 1 to 12 ;
month=vname( oldvars[month_number] );
mean_temp = oldvars[month_number] ;
OUTPUT;
END;
KEEP state Month Mean_Temp;
RUN;
SAS 有一些作业,但我似乎找不到正确的方法。希望你们中的一些人能够提供帮助。
我们从一个 table 开始,其中我们有以下变量:
City State Temp January Temp Feb Temp Mar ... Temp Dec
首先,我们必须计算平均温度(每月,因此对于 12 个不同的变量)和每个州(因此每个州总是有几个城市)。
我使用了这个代码:
PROC SORT DATA=Homework;
BY state;
RUN;
PROC MEANS DATA=Homework;
VAR JAN FEB MAR APR MAY JUN JUL AUG SEP OCT NOV DEC;
BY State
OUTPUT OUT=MTSM (DROP=_type_ _freq_) MEAN=;
RUN;
我的结果是 table,其中我有 53 行(每个州一行)和每月 1 列(第一列用于各州)。像这样:
State JAN FEB ... DEC
State1 xjan xfeb ... xdec
State2
...
State53
现在我需要使用 Array statement
以长格式制作新的 table:
State Month Mean_temp
State1 JAN xjan
state1 FEB xfeb
. MAR ...
. APR ...
. ... ...
State1 DEC xdec
State 2 JAN ...
...
DEC
...
State53 JAN
FEB
...
有人知道如何做到这一点吗?我完全迷路了。 这是我试过的:
DATA MTSM2;
SET MTSM;
BY state;
ARRAY newvars {1} Mean_Temp;
ARRAY oldvars {1, 12} JAN FEB MAR APR MAY JUN JUL AUG SEP OCT NOV DEC;
DO Month = JAN to DEC;
DO k=1;
newvars{k} = oldvars{k, Month};
END;
OUTPUT;
END;
KEEP state Month Mean_Temp;
RUN;
我收到以下错误:ERROR: Array subscript out of range at line 30 column 22
:'(
我做错了什么?我一直在以多种方式更改它,但总是得到相同的错误。
提前致谢!
听起来您只是想使用 Class 语句而不是 By 语句?
您可以通过在 proc means
/proc summary
:
output
语句来获得您想要的 table
/*Generate some dummy data*/
data have;
call streaminit(1);
do j = 1 to 10;
do state = 'a', 'b', 'c';
array months[12] m1-m12;
do i = 1 to dim(months);
months[i] = rand('uniform');
end;
output;
end;
end;
drop i j;
run;
proc summary nway data = have;
var m1-m12;
class state;
output out = want(drop = _TYPE_ _FREQ_) mean=;
run;
如果作业是旋转数据,使用 ARRAY
,从分类组织布局 (state
/month
/mean
) 到宽布局 ( state
/month-1
...month-12
)可以用BY
处理和index
判断来填充一个数组。
基本上每个 BY
组将有一行输出。
一种方法是使用 DOW 循环,其中 SET
语句位于显式循环内。
data want(keep=state jan--dec);
do until (last.state);
set have;
by state;
array months jan feb mar apr may jun jul aug sep oct nov dec;
index = (index('JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC', trim(month))+2)/3;
months(index) = mean;
end;
run;
如果已知数据每个月都有,则不需要索引'lookup',直接从do循环索引变量中获取:
data want(keep=state jan--dec);
do _n_ = 1 by 1 until (last.state); /* repurpose _n_ */
set have;
by state;
array months jan feb mar apr may jun jul aug sep oct nov dec;
months(_n_) = mean;
end;
run;
更新
使用 array
将数据从 across 布局旋转到 down 布局。在数组元素和循环内的 output
name/value 对上迭代一个循环。
data want (keep=state month percent);
set have;
array months jan feb mar apr may jun jul aug sep oct nov dec;
do _n_ = 1 to dim(months);
month = vname(months(_n_)); /* name */
percent = months(_n_); /* value */
OUTPUT;
end;
run;
Proc TRANSPOSE
可以进行相同的数据转换。
当您想同时转置两个或多个数组时,基于数组的旋转非常有用。一个例子是如果你有变量
jan_percent
到dec_percent
和jan_rating
到dec_rating
您想转换成 month
/percent
/rating
的数据形式。 TRANSPOSE
的这种转换需要多个 proc 步骤(每个数组一个)。
你们很亲近。
没有必要为新变量使用 ARRAY,因为它只是一个。列出实际变量名称后,无需告诉 SAS 数组中有多少个变量。并且数组由整数而不是字符串索引。您可以使用 VNAME()
函数在数组中查找由索引寻址的变量的名称。不需要 BY 语句。
DATA MTSM2;
SET MTSM;
ARRAY oldvars JAN FEB MAR APR MAY JUN JUL AUG SEP OCT NOV DEC;
length month mean_temp 8;
DO month_number = 1 to 12 ;
month=vname( oldvars[month_number] );
mean_temp = oldvars[month_number] ;
OUTPUT;
END;
KEEP state Month Mean_Temp;
RUN;