SAS中每列分为​​子列时如何导入excel文件

How to import excel file when each column divides into sub columns in SAS

我有一个 excel 文件,其中每一列都分为子列。我尝试通过以下方式导入它

PROC IMPORT DATAFILE="path\IRCC_M_PRadmiss_0002_E (1).xls"
     OUT=immigrants
     DBMS=XLS REPLACE;
     getnames=yes;
    
RUN;

但是通过这种方式,我将列名作为观察结果。我想以更结构化的方式导入它,以便可以通过名称访问列。 Link 到 excel 文件:https://files.fm/u/bapkwx7mk

Excel 文件似乎包含一个基于某些其他分类数据源的数据透视表 table。如果您有权访问该数据源,请改为导入它。

假设Excel文件是从某个政府网站下载的,原始数据不可用。

正如您所发现的那样,由于 header 单元格中的混合类型和 header 列中的值会污染平面导入,因此单个简单的 IMPORT 将使所有列成为字符。

一个枢轴 table 有三个部分

  • 列headers(class变量的交叉)
    • 您文件中的 table 跨越了三个变量
      YearQuarter月份
  • 行headers(class变量的交叉)
    • 你文件中的table越过一个变量
      国家
  • 数据部分(维度相交的单元格)
    • 您的 table 包含计数总计

Proc IMPORT 可以从 Excel 文件中读取单元格范围,这就产生了以下 取消枢轴旋转的策略 table :

  • 导入列 header 部分,
  • 将行 header 和数据部分一起导入。这是可以做到的,因为行 header 是一维的。
  • TRANSPOSE 列 header 部分和行 header + 数据部分并合并成最终的分类形式。
    • 合并会将分类(或 class)值(国家、年份、季度和月份)关联到每个数据单元格。

IMPORTING with GETNAMES=NO 将产生一个 raw 起点,其中来自 Excel 的每一列将被命名为 F<nn> 。转置原始数据后,您将有一个名为 _NAME_ 的新列,其值将为 "F<nn>"。列名刚刚成为数据。

查看数据部分的单元格,每行有 98 列,转置后会变成 98 行。但是,totals 列可以舍弃,您将剩下 72 行(转置)对应 6 年 * 12 months/year.

将 IMPORT 转换为分类时间后,可以使用 Proc TABULATE 复制原始报告。

示例:

_NAME_ 变量的值使用从列 header 转置构建的自定义信息映射到相应的月份。

* read column headers;

PROC IMPORT DATAFILE="C:\Users\Richard\Downloads\IRCC_M_PRadmiss_0002_E (1).xls"
  REPLACE OUT=headers_raw
  ;
  RANGE="A3:CT5";
  GETNAMES=NO;
RUN;

* read row header and data part (the counts);

PROC IMPORT DATAFILE="C:\Users\Richard\Downloads\IRCC_M_PRadmiss_0002_E (1).xls"
  REPLACE OUT=data_raw
  ;
  RANGE="A6:CT204";
  GETNAMES=NO;
RUN;

proc transpose data=headers_raw 
  out=headers_tall(
    drop=_label_
    where=(col3 not contains 'Total' and col2 not contains 'Total')
  );
  var F2-F98;
run;

* construct special CNTLIN data set for custom informat named FIELD_TO_MONTH;

data headers_cntlin;
  length start  label 8;

  if _n_ = 1 then do;
    hlo = 'O';
    label = .;
    output;
    hlo = '';
  end;

  set headers_tall;
  retain year;
  if not missing (col1) then year = input(col1,4.);

  retain fmtname 'FIELD_TO_MONTH' type 'i';

  month = input (cats('01',col3,year), date9.);

  start = _name_;
  label = month;
  output;

  keep fmtname start label type hlo;
run;

* build the custom informat;

proc format cntlin=headers_cntlin;
run;

* F1 is the one-dimensional row header;
* F2-F98 are the data cells;
* after transpose the column names will be data in column _NAME_;

proc transpose data=data_raw
  out=data_tall(
    drop=_label_ 
    rename=(F1=Country col1=count)
    index=(_name_)
  );
  by F1 notsorted;
  var F2-F98;
run;

data immigration;
  set data_tall;
  label Country=' ';

  * map field name to month per column headers;

  month = input(_name_,FIELD_TO_MONTH.);
  if not missing(month);

  * variables for wider temporal aggregations in time hierarchy year/qtr/month;

  year = year(month);  
  qtr  = qtr(month);   format qtr NLSTRQTR2.1;

  format month monname3.;

  keep country year qtr month count;
run;

* reproduce the Excel pivot table in SAS;

ods html file='immigration.html' style=plateau;

proc tabulate data=immigration;
  class year qtr month / order=internal;
  class country;
  var count;

  table 
    country
    ,
    ( year=''
    * ( qtr=''
      * ( month='' 
          all
        )
        all
       )
       all
    )
    * count='' * sum=' ' * f=comma12.
    ;
run;

ods html close;

Headers 原始(来自范围)

原始数据(来自范围)

Headers 身高

Headers 自定义信息的 CNTLIN FIELD_TO_MONTH

数据高(每个国家 72 行,6 年 12 个月/年)

将信息格式应用于字段名称 (F2....) 以计算时间层次结构变量后的迁移

原创 table 由 TABULATE

转载