了解SAS上表格上的开始日期和最新日期
我是一名非常新的学生,因此对SAS的世界非常熟悉,虽然我去年在学习期间使用过SAS,但理论知识与实际操作知识不同 这是我的问题 我有SAS上的表,如下例所示:了解SAS上表格上的开始日期和最新日期,sas,Sas,我是一名非常新的学生,因此对SAS的世界非常熟悉,虽然我去年在学习期间使用过SAS,但理论知识与实际操作知识不同 这是我的问题 我有SAS上的表,如下例所示: table1 date var_1 var_2 var_3 var_4 var_5 1957M1 . . . . . 1957M2 . . . . 23.5 1957M3 . 1.2 .
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将于1957年10月(或M10)开始,最晚的日期是1957年12月(或M12)
var_4将于1957年10月(或M10)开始,最晚日期为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;
procsqlnoprint;
挑选
最小值(输入(子字符串(日期,1,4),日期4.),
最大值(输入(substr(日期,1,4),日期4.))
从…起
表1
哪里
变量2“
退出
对于我的查询,日期列是文本。我正在尝试通过我的查询将其转换为只包含年份的日期格式,尽管我将只包含年份,拥有月份会很好
我的老板告诉我关于PROC-FREQ
以实现我想要的结果,但我不知道如何实现
如果你有任何线索,我就要了
干杯。您的问题是您的数据结构并不适合您的问题 正确的数据结构是更垂直的结构,包含日期、VAR和值。然后
PROC意味着
非常适合您的需要
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;
如果性能有问题,这是我知道的最快的方法,因为它只需要读取一次数据。使用Joe的代码创建“have”数据集:
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;
通常我不建议这样计算开始日期和结束日期,除非性能是一个考虑因素,或者如果这段代码最终比其他代码更简单
大多数情况下,您最好以不同的方式准备数据结构,尽管在某些情况下,使用上述格式的数据也是有利的 仅供参考,我怀疑
PROC-FREQ
解决方案基本上与我下面的解决方案做了相同的事情-通过PROC-FREQ将其转换为垂直表。嗨,乔,谢谢你的回答。然而,我有一个问题。这是进行转置的唯一方法吗?这当然不是唯一的方法,但这是一个非常好的方法。几乎任何其他方式都需要分别为每个var编码。问题是,从某种意义上说,你的数据与你的数据相差90度(无论如何,对于这个问题)。好吧,就像我说的,你可以使用PROC FREQ做与我上面做的基本相同的事情-这很容易做到。我不确定哪个更快;我倾向于使用数据步骤,因为它更清楚你在做什么,但是PROC-FREQ可能会快一点。这段代码对我来说毫无意义。我认为它基本上是在做我的代码正在做的事情,但是还有很多步骤。这些数据步骤中的大多数都是无用的。这是一个宏编程的好例子,你不应该使用宏编程。我会的。真的有那么糟糕。嗨,罗伯特,为解决方案干杯。最好的,