知道SAS桌面上的开始日期和最新日期

时间:2014-04-28 14:13:53

标签: sas

我在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要达到我想要的结果,但我不知道怎么做。

如果你有任何线索,我会接受它。

干杯。

2 个答案:

答案 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;

通常情况下,我不建议以这种方式计算开始和结束日期,除非考虑性能,或者此代码最终比替代方案更简单。

大多数情况下,您最好以不同方式准备数据结构 - 尽管在某些情况下,以上述格式提供数据也是有利的。