如何将Excel数据导入SAS
问题的原因是:用户想要将Excel数据导入SAS,但是之前的行中存在非空数据,导致导入失败。
解决方法是:
1. 首先,将Excel文件设置为SAS的库(libname),并指定文件路径。
2. 然后,创建一个数据集(data)来存储导入的数据,使用set语句将Excel的表格(Sheet1)导入到数据集中。
3. 最后,清除Excel文件的库(libname)。
下面是解决方法的代码示例:
libname xl excel 'C:\somefile.xlsx';
data sheet;
set xl.'Sheet1$'n;
run;
libname xl clear;
需要注意的是,这种方法适用于64位的SAS 9.4和64位的Excel。如果SAS是64位的而Excel是32位的,可能会出现意外的问题。
如何将Excel数据导入SAS
在SAS 9.2中,我解决了一个类似的问题,使用两个步骤导入,一个用于探索工作表,一个用于提取数据。
以下是我在那里做的泛化,但请原谅我发布未经测试的代码:我的电脑上没有安装SAS。
假设您的数据可能如下所示(保存为制表符分隔的文件):
Some title that does not interust us
Author Dirk Horsten
Date 01-Jan-15
Other Irrelevant thing
Bar Foo Val Remark
A Alfa 1 This is the first line
B Beta 2 This is the second line
C Gamma 3 This is the last line
因此,实际数据从单元格C6开始,列标题为"Bar"。我们还假设我们知道如何找到列"Foo","Bar"和"Val",以及可能不感兴趣的其他列,顺序未知,并且我们事先不知道有多少数据行。
现在,我们先天真地导入工作表,然后查询sasHelp以了解读取了什么:
/** 第一步导入,用于探索工作表的内容 **/
proc import datafile="&file_name" out=temp_out dbms=excelcs replace;
sheet="&sheet_name";
run;
/** 查看SAS读取的内容 **/
proc sql;
select count(*) into :nrColstempCos separated by ' '
from sashelp.vcolumn where libName = 'WORK' and memName = 'TEMP_OUT';
select name into :tempCos separated by ' '
from sashelp.vcolumn where libName = 'WORK' and memName = 'TEMP_OUT';
quit;
接下来,我们查找标题和数据,以便正确读取它:
如果所有列都被解释为字符值,那么这将起作用,但不幸的是,Excel不能强制执行此操作。
data _null_;
set temp_out end=last;
array temp {*} &tempCols.;
retain foo_col bar_col val_col range_bottom 0;
if not (foo_col and bar_col and val_col) then do;
range_left = 0;
range_right = 0;
/* 找出是否最终找到了标题 */
do col = 1 to &nrCols.;
select (upcase(temp(col)));
when ('FOO') do;
foo_col = col;
if not range_left then range_left = col;
rang_right = col;
end;
when ('BAR') do;
bar_col = col;
if not range_left then range_left = col;
rang_right = col;
end;
when ('VALUE') do;
val_col = col;
if not range_left then range_left = col;
rang_right = col;
end;
otherwise;
end;
end;
if (foo_col and bar_col and val_col) then do;
/** 记住标题的位置 **/
range_top = _N_ + 1;
call symput ('rangeTop', range_top);
rangeLeft = byte(rank('A') + range_left - 1);
call symput ('rangeLeft', rangeLeft);
rangeRight = byte(rank('A') + range_right - 1);
call symput ('rangeRight', rangeRight);
end;
end;
else do;
/** 找出是否在此行上存在数据 **/
if (temp(foo_col) ne '' and temp(bar_col) ne '' and temp(val_col) ne '')
then range_bottom = _N_ + 1;
end;
/** 记住最后一个数据的位置 **/
if last then call symput ('rangeBottom', range_bottom);
run;
为了计算rangeTop和rangeBottom,我们考虑到SAS中的第N个观察来自Excel中的第N+1行,因为第一行被解释为标题。
为了计算rangeLeft和rangeRight,我们必须找到相对于要读取的范围中的左列的位置,并将其转换为字母。
现在,我们只读取相关的数据:
/** 第二步导入,读取实际数据 **/
proc import datafile="&file_name" out=&out_ds dbms=excelcs replace;
sheet="&heet_name";
range="&rangeLeft.&rangeTop.&rangeRight.&rangeBottom.";
run;
成功。如果您的计算机上安装了SAS并且正确,请随意测试此代码并进行更正。