SAS:使用PROC SQL将日期变量写入SAS数据集

SAS:使用PROC SQL将日期变量写入SAS数据集,sql,macros,sas,proc-sql,Sql,Macros,Sas,Proc Sql,我正在SAS中编写一段代码,用于提取给定时间序列数据列中的最后一个非空值及其对应的日期,然后将它们插入新的数据集中。到目前为止,SQL似乎是实现这一点的最简单方法,所以我一直在使用SQL 我从中读取的数据集称为rtchg1,在早期代码中从.xlsx电子表格导入。它由一个日期变量和一组时间序列变量组成 data rtchg1; set rtchg1; where date between '1FEB1959'd and '1OCT1998'd; run; 我要写的表是Forecast,它是用一些

我正在SAS中编写一段代码,用于提取给定时间序列数据列中的最后一个非空值及其对应的日期,然后将它们插入新的数据集中。到目前为止,SQL似乎是实现这一点的最简单方法,所以我一直在使用SQL

我从中读取的数据集称为rtchg1,在早期代码中从.xlsx电子表格导入。它由一个日期变量和一组时间序列变量组成

data rtchg1;
set rtchg1;
where date between '1FEB1959'd and '1OCT1998'd;
run;
我要写的表是Forecast,它是用一些简单的SQL创建的:

PROC SQL ;
    CREATE TABLE Forecasts
    (Date date,      
     Forecast num);
run;    
我以前将“日期”的格式设置得更复杂,遇到了同样的问题。如果我在这里做错了什么,请告诉我,任何关于如何改进我的代码的建议都将不胜感激

最后,我开发了以下宏来提取数据:

%macro scoreprep(readtable,datevar,writetable); 
%do i=1 %to 3;

    %let currentvar=%scan(&periods,&i);

    proc sql;
        select &datevar, &currentvar into :date1, :LEI
        from &readtable
        where &currentvar is not null
        having &datevar=max(&datevar);

        insert into &writetable (Date, Forecast)
            values ("&date1"d, &LEI);
    quit;

%end;
%mend;

%scoreprep(rtchg1,date,Forecasts); 
现在它只从1到3,以便在没有太多等待时间的情况下对其进行测试。这里的一切似乎都工作得很好,除了将日期变量插入表中。当我删除日期变量并只输入&LEI时,它将其写入预测表,没有任何问题。当我按原样运行代码时,会出现以下错误:

错误:无效的日期/时间/日期时间常数“10/01/1968”d.


我真的不确定从这里到哪里去,无论我在哪里转换宏变量的格式,似乎都没有什么能正常工作。如蒙指教,不胜感激。此外,如果您在我的代码中看到任何您不喜欢的内容,请随意批评。我确实知道在Excel中实现这一点的更简单的方法,但这种方法更有趣:)

尝试这样更改这一行,看看是否有帮助:

    select &datevar format=date9., &currentvar into :date1, :LEI

由于要将值提取到字符串中,因此需要告诉SAS如何将该字符串转换回日期。明确你是如何进行转换的。首先生成宏变量,然后生成VALUES()语句。所以,如果预测是一个数字,那么它应该只在精度损失最小的情况下工作

select put(&datevar,date9.) ,put(&currentvar,best32.) into :date1 ,:LEI
...
values ("&date1"d, &LEI)
但是如果它是一个字符变量,那么您可能希望使用它

select put(&datevar,date9.), quote(&currentvar) into :date1,:LEI
...
values ("&date1"d, &LEI)
还要确保用作日期源的变量实际具有日期值,而不是日期时间值。如果is具有日期时间值,则可以使用
DTDATE
格式以正确的格式生成宏变量。或者使用datepart()函数仅提取日期值

请注意,将数据放入宏变量中只是为了稍后将其放回数据中是没有意义的。所以您可以使用PROC APPEND

%macro scoreprep(readtable,datevar,writetable);
%local currentvar i ;
%do i=1 %to %sysfunc(countw(&periods));
  %let currentvar=%scan(&periods,&i);
proc sql;
  create table to_add as
    select &datevar as date 
         , &currentvar as forecast
    from &readtable
    where &currentvar is not null
    having &datevar=max(&datevar)
  ;
quit;
proc append data=to_add base=&writetable force ;
run;

%end;
%mend;

%scoreprep(rtchg1,date,Forecasts);
甚至只使用SQL代码插入查询结果

insert into &writetable (date,forecast)
  select &datevar, &currentvar
    from &readtable
    where &currentvar is not null
    having &datevar=max(&datevar)
;

有趣!这种方法比我使用的方法更省时吗?忽略前面的评论(已删除的评论),这非常有效!我看错表了,哈哈。最大的区别在于准确度。如果将数据移动到宏变量中,则将其转换为文本。除了格式可能导致的混乱之外,它还可能在数字上失去一些精度。SAS将数字存储为IEEE浮点值。添加了代码,以回答如何使数据->宏变量->数据往返工作的原始问题。从效率方面来说,您可能希望以某种方式格式化数据,以便单个进程可以在一次传递中生成所需的所有数据行。如果您的数据格式正确,您很可能可以使用PROC SUMMARY执行此操作。我尝试过,但遇到了一个稍微不同的问题,我在代码末尾尝试将&date1转换为日期变量之前看到的类型:>错误202-322:该选项或参数无法识别,将被忽略。此查询是否从表中返回多行?如果没有,那么这应该可以工作,否则您需要修改查询。它只返回一行,在尝试将&datevar插入表时,它似乎拒绝将其识别为datevariable&datevar总是直接从日期列中提取,所以这对我来说很奇怪。