SAS:在宏中从开始日期迭代到结束日期

SAS:在宏中从开始日期迭代到结束日期,sas,Sas,我有这样一个数据集: DATA tmp; INPUT identifier $ d0101 d0102 d0103 d0104 d0105 d0106 d0107 d0108 d0109 d0110 d0111 d0112 ; DATALINES; a 1 2 3 4 5 6 7 8 9 10 11 12 b 4 5 7 4 5 6 7 6 9 10 3 12 c 5 2 3 5 5 4 7 8 3

我有这样一个数据集:

DATA tmp;
    INPUT
        identifier $
        d0101 d0102 d0103 d0104 d0105 d0106
        d0107 d0108 d0109 d0110 d0111 d0112
    ;
    DATALINES;
    a 1 2 3 4 5 6 7 8 9 10 11 12
    b 4 5 7 4 5 6 7 6 9 10 3 12
    c 5 2 3 5 5 4 7 8 3 1 1 2
    ;
RUN;
DATA tmp;
    INPUT
        identifier $ day value
    ;
    DATALINES;
    a '01JAN2018'd 1
    a '02JAN2018'd 2
    a '03JAN2018'd 3
    a '04JAN2018'd 4
    a '05JAN2018'd 5
    a '06JAN2018'd 6
    a '07JAN2018'd 7
    a '08JAN2018'd 8
    a '09JAN2018'd 9
    a '10JAN2018'd 10
    a '11JAN2018'd 11
    a '12JAN2018'd 12
    b '01JAN2018'd 4
    b '02JAN2018'd 5
    b '03JAN2018'd 7
    ...
    ;
RUN;
我正在尝试创建一个数据集,如下所示:

DATA tmp;
    INPUT
        identifier $
        d0101 d0102 d0103 d0104 d0105 d0106
        d0107 d0108 d0109 d0110 d0111 d0112
    ;
    DATALINES;
    a 1 2 3 4 5 6 7 8 9 10 11 12
    b 4 5 7 4 5 6 7 6 9 10 3 12
    c 5 2 3 5 5 4 7 8 3 1 1 2
    ;
RUN;
DATA tmp;
    INPUT
        identifier $ day value
    ;
    DATALINES;
    a '01JAN2018'd 1
    a '02JAN2018'd 2
    a '03JAN2018'd 3
    a '04JAN2018'd 4
    a '05JAN2018'd 5
    a '06JAN2018'd 6
    a '07JAN2018'd 7
    a '08JAN2018'd 8
    a '09JAN2018'd 9
    a '10JAN2018'd 10
    a '11JAN2018'd 11
    a '12JAN2018'd 12
    b '01JAN2018'd 4
    b '02JAN2018'd 5
    b '03JAN2018'd 7
    ...
    ;
RUN;
我知道这样“融化”数据集的语法——我已经完成了一个类似的宏,用于表示一年中12个月中每个月的特定值的列

我正在努力解决的是如何遍历一年中迄今为止的所有天数(假设
have
数据集将年初至今的所有天数作为列)

我已经习惯了Python,所以我可能会在那里做一些事情:

>>> import datetime
>>> 
>>> def dates_ytd():
...     end_date = datetime.date.today()
...     start_date = datetime.date(end_date.year, 1, 1)
...     diff = (end_date - start_date).days
...     for x in range(0, diff + 1):
...         yield end_date - datetime.timedelta(days=x)
... 
>>> def create_date_column(dt):
...     day, month = dt.day, dt.month
...     day_fmt = '{}{}'.format('0' if day < 10 else '', day)
...     month_fmt = '{}{}'.format('0' if month < 10 else '', month)
...     return 'd{}{}'.format(month_fmt, day_fmt)
... 
>>> result = [create_date_column(dt) for dt in dates_ytd()]
>>> 
>>> result[:5]
['d1031', 'd1030', 'd1029', 'd1028', 'd1027']
>>> result[-5:]
['d0105', 'd0104', 'd0103', 'd0102', 'd0101']

当我运行它时,使用
%ITER\u DATES\u YTD(),甚至没有打印到我的日志中。我错过了什么?我基本上希望遍历“YTD”列,如
d0101
d0102
d0103
,这与其说是宏/数据步骤问题,不如说是一个换位问题

核心问题是元数据中有数据,这意味着“日期”在列名中编码

示例1:

转换数据,然后使用
d
\u name\u
值计算实际日期

proc transpose data=have out=have_t(rename=col1=value);
  by id;
run;

data want (keep=id date value);
  set have_t;

  * convert the variable name has day-in-year metadata into some regular data;
  date = input (cats(year(today()),substr(_name_,2)),yymmdd10.);

  format date yymmdd10.;
run;
示例2:

执行基于数组的换位。
D
变量在_日期被用作值_的角色,并且由于一致的命名约定,很容易排列。
VNAME
函数从数组引用中提取原始变量名,并从
部分计算日期值

data want;
  set have;
  array value_at_date d:;

  do index = 1 to dim(value_at_date);
    date = input(cats(year(today()),substr(VNAME(value_at_date(index)),2)), yymmdd10.);
    value = value_at_date(index);
    output;
  end;

  format date yymmdd10.;
  keep id date value;
run;

这与其说是宏/数据步问题,不如说是一个换位问题

核心问题是元数据中有数据,这意味着“日期”在列名中编码

示例1:

转换数据,然后使用
d
\u name\u
值计算实际日期

proc transpose data=have out=have_t(rename=col1=value);
  by id;
run;

data want (keep=id date value);
  set have_t;

  * convert the variable name has day-in-year metadata into some regular data;
  date = input (cats(year(today()),substr(_name_,2)),yymmdd10.);

  format date yymmdd10.;
run;
示例2:

执行基于数组的换位。
D
变量在_日期被用作值_的角色,并且由于一致的命名约定,很容易排列。
VNAME
函数从数组引用中提取原始变量名,并从
部分计算日期值

data want;
  set have;
  array value_at_date d:;

  do index = 1 to dim(value_at_date);
    date = input(cats(year(today()),substr(VNAME(value_at_date(index)),2)), yymmdd10.);
    value = value_at_date(index);
    output;
  end;

  format date yymmdd10.;
  keep id date value;
run;

要遍历日期,必须首先将其转换为数字,然后从中提取日期部分

%macro iterateDates();
    data _null_;
        %do i = %sysFunc(inputN(01012018,ddmmyy8.)) %to %sysFunc(today()) %by 1;
            %put d%sysFunc(putN(&i, ddmmyy4.));
        %end;
    run;
%mend iterateDates;

%iterateDates();

我认为'01012018'd仅在数据步骤中处理,而不是在宏代码中处理。请记住,宏代码是首先执行的,只有在执行数据步骤之后才执行。您可以将其视为使用SAS宏构建SAS代码,然后运行它。

要遍历日期,必须先将其转换为数字,然后从中提取日期部分

%macro iterateDates();
    data _null_;
        %do i = %sysFunc(inputN(01012018,ddmmyy8.)) %to %sysFunc(today()) %by 1;
            %put d%sysFunc(putN(&i, ddmmyy4.));
        %end;
    run;
%mend iterateDates;

%iterateDates();

我认为'01012018'd仅在数据步骤中处理,而不是在宏代码中处理。请记住,宏代码是首先执行的,只有在执行数据步骤之后才执行。您可以将其视为使用SAS宏构建SAS代码,然后运行它。

您是否已经有了SAS数据集?或者你只是有一个看起来像你的数据线的原始文本文件?如果您有该格式的原始数据,则直接将其读入垂直结构并不困难。这是一个SAS数据集,其中的
d0101
d0102
列作为标题。因此,后续问题是,您是否可以修复源以更易于使用的另一种格式交付数据?您是否已经有SAS数据集?或者你只是有一个看起来像你的数据线的原始文本文件?如果您有该格式的原始数据,那么直接将其读入垂直结构并不困难。这是一个SAS数据集,其中的
d0101
d0102
列作为标题。因此,接下来的问题是,您能否修复源,以更易于使用的另一种格式传递数据?