【问题标题】:How to create date field using the date from data filename in SAS?如何使用 SAS 中数据文件名中的日期创建日期字段?
【发布时间】:2025-12-12 20:15:01
【问题描述】:

如何从文件名中获取日期以填充日期列?

我有 23 个数据文件:

price_20070131
price_20070228
price_20070331
.
.
.
price_20081130

在数据文件 price_20070131 中,目前如下所示:

ID     Product    
001       A    
002       B      
003       C   

我希望我的输出如下所示:

ID     Product     Date
001       A      31Jan2007
002       B      31Jan2007 
003       C      31Jan2007

将对所有 23 个数据文件重复相同的操作。最终结果将合并所有 23 个文件,如下所示:

ID     Product     Date
001       A      31Jan2007
002       B      31Jan2007 
003       C      31Jan2007
001       A      28Feb2007
002       B      28Feb2007 
003       C      28Feb2007
.
.
.
.
001       A      30Nov2007
002       B      30Nov2007 
003       C      30Nov2007

【问题讨论】:

标签: loops date macros sas append


【解决方案1】:

使用 INDSNAME 选项添加文件名,然后使用 SCAN/SUBSTR() 提取日期部分。这将追加以 price_2007 和 price_2008 开头的所有数据集并添加一个日期字段。

 data want;
    set price_2007: price_2008: indsname=source;
    date=input(scan(source, 2, '_'), yymmdd10.);
    format date date9.;
 run;

编辑:SAS 9.1 大约有 15 年的历史,所以你真的应该升级。升级包含在您的许可证中。这意味着您没有数据集列表或使用 INDSNAME 选项的能力,并且意味着您需要某种宏解决方案。 4行代码变成47...

假设您的数据集始终命名为 PRICE_LAST_DAY_MONTH。

*sample data sets for demonstration;
data price_20080131;
set sashelp.class;
test=1;
run;

data price_20080229;
set sashelp.class;
test=2;
run;

%macro stack_data_add_date(start_date=, end_date=, outData=, debug=);

    %*get parameters for looping, primarily the number of intervals;
    data _null_;
        start_date= input("&start_date", yymmdd10.);
        end_date = input("&end_date", yymmdd10.);
        n_intervals = intck('month', start_date, end_date);

        call symputx('start_date', start_date, 'l');
        call symputx('end_date', end_date, 'l');
        call symputx('n_intervals', n_intervals, 'l');
    run;

    %*loop from 0 - starting time to end;
    %do i=0 %to &n_intervals;

    %*determine end of month date for dataset name;
    %let date = %sysfunc(intnx(month, &start_date, &i., e));

    %*output statistics for testing;
    %if &debug=Y %then %do;
        %put &n_intervals;
        %put &start_date;
        %put &end_date;
    %end;

    %*create a view with the data and date added in;
    data _temp / view=_temp;
    set price_%sysfunc(putn(&date, yymmddn8.));
    date = &date.;
    format date date9.;
    run;

    %*insert into master table;
    proc append base=&outData data=_temp;
    run;

    %*delete view so it doesn't exist for next loop;
    proc datasets lib=work nodetails nolist;
    delete _temp / memtype=view;
    run;quit;

%end;


%mend;

*test;
%stack_data_add_date(start_date=20080131, end_date=20080229, outData=want, debug=Y);

【讨论】:

  • 显然,您也可以使用filename 代替indsname。见communities.sas.com/t5/Base-SAS-Programming/…。是同义词吗?
  • @DirkHorsten SET 语句中没有 FILENAME= 选项。您正在考虑 INFILE 语句。您需要哪个取决于您获得的文件类型。 SAS 数据集?还是原始文本文件?
  • FILENAME 用于文本文件,indsname 用于 SAS 数据集。
  • 糟糕,我确实搞混了。
  • 不幸的是,我使用的是 SAS 9.1。 INDSNAME 选项在 SAS 9.1 上不起作用