Import 在sas中读取带有日期列的excel文件

Import 在sas中读取带有日期列的excel文件,import,sas,sas-macro,Import,Sas,Sas Macro,在将excel文件导入sas环境时,我遇到了一个问题。因此,基本上在Excel文件中,很少有列被命名为 Geography AR_NO 31-Jan-18 28-Feb-18 31-Mar-18 30-Apr-18 31-May-18 30-Jun-18 使用以下代码后-> %macro FX_Lkup(sheet); FILENAME FXFILE "/idn/home/Module2/excel.xlsx"; PROC IMPORT DATAFI

在将excel文件导入sas环境时,我遇到了一个问题。因此,基本上在Excel文件中,很少有列被命名为

Geography   
AR_NO   
31-Jan-18   
28-Feb-18   
31-Mar-18   
30-Apr-18   
31-May-18   
30-Jun-18
使用以下代码后->

%macro FX_Lkup(sheet);
FILENAME FXFILE "/idn/home/Module2/excel.xlsx";

PROC IMPORT DATAFILE=FXFILE
       DBMS=XLSX
       OUT=&sheet. 
       REPLACE
       ;
       SHEET="&sheet."; 
       RUN;

%mend FX_Lkup;
%FX_Lkup(LENDING_TEMPLATE);
%FX_Lkup(2018FXRates);

SAS data print the columns as 
    Geography   
    AR_NO   
    43131
    43159
    43190
    43220
and so on.
有什么解决办法吗?任何潜在客户都将不胜感激:)


谢谢

正确导入后,SAS使用数字存储日期。为了在最终表格中有一个日期,您需要声明
format=AFRDFDE7。
例如

如果在同一列中有混合字符和数字值,则SAS将被迫将变量创建为字符。当它这样做时,它将Excel用于日期的数字存储为一个数字字符串。要将其转换为SAS中的日期,请首先将数字字符串转换为数字,然后调整数字以说明SAS和Excel计算天数的方式不同

data want ;
  set LENDING_TEMPLATE ;
  date = input(geography,??32.) + '30DEC1899'd;
  format date date9.;
run;
日期作为标题

ods noresults;
ods excel file='%TEMP%\across.xlsx' options(sheet_name='Sample');

data _null_;
  declare odsout xl();

  if 0 then set demo_wide;
  length _name_ $32;

  xl.table_start();
    * header;
    xl.row_start();
      do _n_ = 1 to 100; * 100 column guard;
        call vnext(_name_);
        if _name_ = '_name_' then leave;

        _label_ = vlabelx(_name_);
        _date_ = input(_label_, ?? date9.);

        * make some header cells an Excel date formatted value;

        if missing(_date_) then
          xl.format_cell(data:_label_);
        else
          xl.format_cell(
            data:_date_,
            style_attr:"width=9em tagattr='type:DateTime format:dd-mmm-yy'"
          );
      end;
    xl.row_end();

    * data rows;
    do _n_ = 1 by 1 while (not lastrow);
      set demo_wide end=lastrow;

      xl.row_start();
        call missing(_name_);
        do _index_ = 1 to 100; * 100 column guard;
          call vnext(_name_);
          if _name_ = '_name_' then leave;

          xl.format_cell(data:vvaluex(_name_));
        end;
      xl.row_end();
    end;

  xl.table_end();

  stop;
run;

ods excel close;
ods results;
如果excel文件使用日期作为列标题,SAS也会将其转换为数字字符串,因为变量名始终是字符串,而不是数字。一个快速修复它的方法是使用PROC转置。当每一行都由其他变量唯一标识,并且所有“日期”变量都是数字时,这将很容易实现

proc transpose data=LENDING_TEMPLATE out=tall ;
  by geography ar_no ;
run;

data tall ;
  set tall ;
  date = input(_name_ , 32.) + '30DEC1899'd ;
  format date date9. ;
  drop _name_;
run;
您可以到此为止,因为现在有了一个有用的数据集,其中日期值位于变量中,而不是隐藏在元数据(变量名)中

要回到原来的广域布局,只需添加另一个PROC转置,并告诉它使用DATE作为ID变量

 proc transpose data=tall out=wide ;
    by geography ar_no ;
    id date;
    var col1;
 run;

IMPORT
正在使用Excel日期值列标题作为Excel历元日期编号

使用
Proc DATASETS
更改列标签,并可能将列重命名为通用名称,例如
DATE1-DATE6
。或者,继续,并进一步使用列
GEO
AR\u NO
DATE
VALUE

您可能会问自己“这些数字(如
43131
)来自哪里?”或“什么是Excel历元日期数字?”

它们是未格式化的Excel日期值。由数字表示的人类可读日期由系统历元或数字
0
表示的日期确定

不同的计时系统有不同的纪元(起点)和时间单位。一些例子:

  • 21DEC1899
    Excel日期时间编号0,1=1天
  • 1960年1月1日
    SAS日期编号0,1=1天
  • 1960年1月1日
    SAS日期时间编号0,1=1秒
  • 1970年1月1日
    Unix操作系统日期时间编号0,1=1秒
要将Excel日期编号转换为SAS日期编号,需要减去
21916
,这是从
31DEC1899
01JAN1960
的天数

在设置SAS列的标签和重命名列时,将使用对日期年代的理解

对于其他处理代码的人,下面将创建一个Excel工作表,其中包含日期值列标题。我推测,在导入包含Excel数据透视表的工作表时,可能会出现这种情况

首先创建一些示例SAS数据

data demo_tall;
  do Geography = 'Mountains', 'Plains';
  do AR_NO = 1 to 3;
    _n_ = 0;
    length label $200;
    do label = '31-Jan-18', '28-Feb-18', '31-Mar-18',
               '30-Apr-18', '31-May-18', '30-Jun-18'
    ;
        _n_ + 1;
        name = cats('Date',_n_);
        value + 1;
        output;
    end;
  end;
  end;
run;

proc transpose data=demo_tall out=demo_wide(drop=_name_);
  by Geography AR_NO;
  var value;
  id name;
  idlabel label;
run;
样本SAS数据集(使用转置进行数据透视)

然后创建带有Excel日期值和格式化列标题的Excel工作表

ods noresults;
ods excel file='%TEMP%\across.xlsx' options(sheet_name='Sample');

data _null_;
  declare odsout xl();

  if 0 then set demo_wide;
  length _name_ $32;

  xl.table_start();
    * header;
    xl.row_start();
      do _n_ = 1 to 100; * 100 column guard;
        call vnext(_name_);
        if _name_ = '_name_' then leave;

        _label_ = vlabelx(_name_);
        _date_ = input(_label_, ?? date9.);

        * make some header cells an Excel date formatted value;

        if missing(_date_) then
          xl.format_cell(data:_label_);
        else
          xl.format_cell(
            data:_date_,
            style_attr:"width=9em tagattr='type:DateTime format:dd-mmm-yy'"
          );
      end;
    xl.row_end();

    * data rows;
    do _n_ = 1 by 1 while (not lastrow);
      set demo_wide end=lastrow;

      xl.row_start();
        call missing(_name_);
        do _index_ = 1 to 100; * 100 column guard;
          call vnext(_name_);
          if _name_ = '_name_' then leave;

          xl.format_cell(data:vvaluex(_name_));
        end;
      xl.row_end();
    end;

  xl.table_end();

  stop;
run;

ods excel close;
ods results;
已创建Excel文件

导入Excel工作表

日志将显示日期值列标题的“有趣性”

options msglevel=I;

proc import datafile='%temp%\across.xlsx' dbms=xlsx replace out=want;
  sheet = "Sample";
run;

proc contents noprint data=want out=want_meta(keep=name label varnum);
run;
----- LOG -----
1380  proc import datafile='%temp%\across.xlsx' dbms=xlsx replace out=want;
1381    sheet = "Sample";
1382  run;

NOTE:    Variable Name Change.  43131 -> _43131
NOTE:    Variable Name Change.  43159 -> _43159
NOTE:    Variable Name Change.  43190 -> _43190
NOTE:    Variable Name Change.  43220 -> _43220
NOTE:    Variable Name Change.  43251 -> _43251
NOTE:    Variable Name Change.  43281 -> _43281
NOTE: VARCHAR data type is not supported by the V9 engine. Variable Geography has been converted
      to CHAR data type.
NOTE: The import data set has 6 observations and 8 variables.
NOTE: WORK.WANT data set was successfully created.
NOTE: PROCEDURE IMPORT used (Total process time):
      real time           0.01 seconds
      cpu time            0.01 seconds
修改导入数据集的标题(元数据)

日期值列名称将重命名为
DATE1-DATE6
,标签将更改为SAS格式的相应日期
DATE11。
dd mon yyyy


如果有,您能给我举个例子吗?所以您的输出SAS表名应该是sheet right的名称,因此
proc数据集;修改&sheet,;将地理信息格式化为AFRDFDE7。;退出我不确定-您的列名是
地理
AR_NO
?您好,谢谢您的快速回复,但提到的项目是我的列名而不是数据值地理AR_NO 31-Jan-18 28-Feb-18 31-Mar-18 30-Apr-18您是说第一行有“地理”第二行有“AR-NO”其余的有实际的日期值吗?如果是这样,那么SAS将地理变量设置为字符变量,因为数据类型混合。您好,感谢您的快速响应,但是提到的项目是我的列名而不是数据值地理AR_NO 31-Jan-18 28-Feb-18 31-Mar-18 30-Apr-18所以问题中的垂直显示应该表示向下旋转的列标题,而不是一列的内容?您好,谢谢您的快速回复,但是提到的项目是我的列名而不是数据值地理AR_NO 31-Jan-18 28-Feb-18 31-Mar-18 30-Apr-18您可以使用相同的方法将名称转换为日期。但不能给变量指定日期名称。您需要使用有效的名称。或者,如果您使用VALIDVARNAME=ANY,那么您可能会使用类似于这些日期的字符串,但您需要使用名称文字来引用它们,例如,
'31-JAN-2018'n
。您好,感谢您的快速响应,但提到的项目是我的列名,而不是数据值地理AR_NO 31-Jan-18 28-Feb-18 31-Mar-18 30 Apr-18@vmaha更改了答案以显示如何处理日期值列标题。
proc transpose data=want out=stage1(rename=(col1=value _label_=date_string));
  by geography ar_no;
  var date:;
  label _name_ = ' ';
  label date_string = ' ';
run;

data want_tall;
  set stage1;
  date = input (date_string, date11.);
  format date date11.;
  keep geography ar_no _name_ date value;
run;