【问题标题】:How to import excel data into sas如何将excel数据导入sas
【发布时间】:2015-01-02 09:37:59
【问题描述】:

我有 Excel 文件 (.xlsx),它的列名位于第 4 行,数据开头位于第 5 行。我不确定在 SAS 的 Proc Import 中使用什么来提取数据。请帮忙。 谢谢

【问题讨论】:

  • 没有截断空格,你可以使用communities.sas.com/thread/12293?tstart=0中的RANGE参数
  • 问题是范围不会保持不变,我正在尝试自动从 SAS 数据集中的 Excel 导入数据并根据我的要求对其进行处理。
  • 看起来有人写了一个关于如何做到这一点的演练here。我认为您必须将 Excel 文件格式化为 XLS 而不是 XLSX
  • 这些天来,每个人都使用最新版本的 excel(.xlsx),我正在使用这个程序从 10 多个文件中提取数据,因此手动将它们转换为 xls 看起来不是一个好选择,我我希望将整个过程自动化,因此正在寻找解决方案。
  • RANGE 是您唯一真正的选择。我会导入一次,找出数据从哪一行开始,将其保存为宏变量,然后使用 RANGE 重新导入。 DDE 也可以做到,但我觉得这要复杂得多。

标签: sas


【解决方案1】:

我在 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

因此,实际数据从具有列标题“Bar”的单元格 C6 开始。让我们也假设我们知道以未知的顺序找到列“Foo”、“Bar”和“Val”以及可能我们不感兴趣的其他一些列,并且我们不知道有多少数据行。

现在,我们第一次天真地导入工作表并查询 sasHelp 以找出读取的内容:;

/** First stroke import, to explore the content of the sheet **/
proc import datafile="&file_name" out=temp_out dbms=excelcs replace;
    sheet="&sheet_name";
run; 

/** Find out what SAS read in **/
proc sql;
    select couint(*) into :nrColstempCos separ 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;

        /* Find out if we finally found the headers */
        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;
            /** remember where the headers were found **/
            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;
        /** find out if there is data on this line **/
        if (temp(foo_col) ne '' and temp(bar_col) ne '' and temp(val_col) ne '') 
            then range_bottom = _N_ + 1;
    end;

    /** remember where the last data was found **/
    if last then call symput ('rangeBottom', range_bottom);
run;

为了计算 rangeTop 和 rangeBottom,我们考虑到 SAS 中的第 _N_ 个观察值来自 excel 中的第 N+1 行,因为第一个 excel 行被解释为标题。

要计算 rangeLeft 和 rangeRight,我们必须在我们将读取的范围内找到左侧列的相对位置并将其转换为字母

现在我们只读取相关数据

/** Second stroke import, to read in the actual data **/
proc import datafile="&file_name" out=&out_ds dbms=excelcs replace;
    sheet="&heet_name";
    range="&rangeLeft.&rangeTop.&rangeRight.&rangeBottom.";
run; 

成功。如果您的计算机上有 SAS 并更正它,请随意测试此代码。

【讨论】:

    【解决方案2】:

    无论您的数据前面有多少行,以下内容都应该有效,假设您的数据前面的行完全是空白的。

    libname xl excel 'C:\somefile.xlsx';
    
    data sheet;
        set xl.'Sheet1$'n;
    run;
    
    libname xl clear;
    

    这会将您的 Excel 工作簿设置为数据库,并且可以像表格一样直接引用工作表。我应该注意我的设置是 64 位 SAS 9.4 和 64 位 Excel;我的理解是,如果您有 64 位 SAS 和 32 位 Excel,这种方法可能无法按预期工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-10-12
      • 2016-04-02
      • 1970-01-01
      • 1970-01-01
      • 2011-06-26
      • 1970-01-01
      • 2023-03-23
      相关资源
      最近更新 更多