我在SAS的世界里非常新鲜,尽管去年我在学习期间使用过SAS,但理论知识与实践知识并不相同。
这是我的问题。
我在SAS上有表格,如下例所示:
table1
date var_1 var_2 var_3 var_4 var_5
1957M1 . . . . .
1957M2 . . . . 23.5
1957M3 . 1.2 . . 23.6
1957M4 . 1.3 . . 23.7
1957M5 . 1.4 . 0.123 23.8
1957M6 . 1.5 . 0.124 23.9
1957M7 . 1.6 3.0 0.125 23.10
1957M8 . 1.7 3.1 0.126 23.11
1957M9 . 1.8 3.2 0.127 23.12
1957M10 2.1 1.9 3.3 0.128 23.13
1957M11 2.2 1.10 3.4 0.129 23.14
1957M12 2.3 1.11 3.5 0.130 23.15
正如您所猜测的,每个变量本身都是一个时间序列,而日期也是一个时间序列。列是数字的,除了日期列,它是一个字符。
我的目标是了解每个变量,它们各自的开始日期和最新日期。
var_1将于10月(或M10)开始于1957年,最新日期将在12月(或M12)的1957年。
var_4将于10月(或M10)开始于1957年,最晚的日期将是12月(或M12)。
我已经通过SAS尝试了以下一个表作为测试的一个列但是它花费了很长时间,没有结果。
PROC SQL NOPRINT;
SELECT
MIN(input(substr(date,1,4),date4.)),
MAX(input(substr(date,1,4),date4.))
FROM
table1
WHERE
var_2 <> "."
quit;
对于我的查询,日期列是文本。我正在尝试通过我的查询将其转换为仅包含年份的日期格式,尽管因为我只会使用年份而且月份会很棒。
我的老板告诉我PROC FREQ
要达到我想要的结果,但我不知道怎么做。
如果你有任何线索,我会接受它。
干杯。
答案 0 :(得分:1)
您的问题是您的数据结构并不适合您的问题。
正确的数据结构是一个更垂直的结构,具有DATE,VAR,VALUE。然后PROC MEANS
非常适合您的需求。
data have;
input date $ var_1 var_2 var_3 var_4 var_5;
datalines;
1957M1 . . . . .
1957M2 . . . . 23.5
1957M3 . 1.2 . . 23.6
1957M4 . 1.3 . . 23.7
1957M5 . 1.4 . 0.123 23.8
1957M6 . 1.5 . 0.124 23.9
1957M7 . 1.6 3.0 0.125 23.10
1957M8 . 1.7 3.1 0.126 23.11
1957M9 . 1.8 3.2 0.127 23.12
1957M10 2.1 1.9 3.3 0.128 23.13
1957M11 2.2 1.10 3.4 0.129 23.14
1957M12 2.3 1.11 3.5 0.130 23.15
;;;;
run;
data want;
set have;
array var_[5];
date_num = mdy(substr(date,6),1,substr(date,1,4));
do _iter= 1 to dim(var_);
if not missing(var_[_iter]) then do;
var = vname(var_[_iter]);
value = var_[_iter];
output;
end;
end;
format date_num MONYY.;
run;
proc means data=want;
class var;
var date_num;
output out=edge_dates min= max= /autoname;
run;
答案 1 :(得分:1)
如果性能是一个问题,这是我所知道的最快的方式,因为它只需要读取一次数据。使用Joe的代码创建&#39; has&#39;数据集:
data want;
format date_num start1-start5 end1-end5 monyy.;
set have end=eof;
retain start1-start5 end1-end5 .; * RETAIN THE VALUES WE WILL BE CALCULATING AS WE ITERATE ACROSS ROWS IN THE DATASET;
array arr_var [*] var_1-var_5 ; * ARRAY FOR EXISTING VARIABLES;
array arr_start[*] start1-start5; * ARRAY FOR NEW VARIABLES THAT WILL CONTAIN START DATE;
array arr_end [*] end1-end5 ; * ARRAY FOR NEW VARIABLES THAT WILL CONTAIN END DATE;
date_num = mdy(input(substr(date,6),best.),1,input(substr(date,1,4),best.));
do iter=1 to dim(arr_var); * LOOPING FOR THE NUMBER OF VARIABLES IN ARR_VAR;
if arr_var[iter] ne . then do; * ONLY GOING TO PERFORM CALCS WHEN THE VARIABLE IS NOT MISSING;
if arr_start[iter] eq . then do;
arr_start[iter] = date_num; * ONLY UPDATE THE START DATE IF IT HASNT ALREADY BEEN SET;
end;
arr_end[iter] = date_num; * IF ITS NOT MISSING, ALWAYS UPDATE THE END DATE;
end;
end;
if eof then do;
output; * ONLY OUTPUT THE CALCULATED VALUES ONCE WE HIT THE END OF THE DATASET;
end;
keep start: end:; * KEEP ONLY VARS STARTING WITH START OR END;
run;
通常情况下,我不建议以这种方式计算开始和结束日期,除非考虑性能,或者此代码最终比替代方案更简单。
大多数情况下,您最好以不同方式准备数据结构 - 尽管在某些情况下,以上述格式提供数据也是有利的。