2014-11-06 77 views
3

我有Excel文件(.xlsx),它的第四行有列名,第五行有数据。我不知道用什么来提取SAS中的Proc Import中的数据。请帮忙。 谢谢如何将excel数据导入sas

+2

缺少截断空格,您可能能够使用范围参数在https://communities.sas.com/thread/12293?tstart=0 – NoChance 2014-11-06 01:11:50

+0

问题是范围不会是恒定的,我试图自动从SAS数据集中的Excel中导入数据并根据我的要求处理它。 – user2694624 2014-11-06 01:21:35

+0

看起来有人写了一篇关于如何做到这一点的文章(http://www.ciser.cornell.edu/faq/sas/excel2sas.shtml)。我认为你必须将你的Excel文件格式化为XLS而不是XLSX – davidcondrey 2014-11-06 01:56:13

回答

0

无论您的数据前面有多少行,提供了以下数据的行都完全是空白。

libname xl excel 'C:\somefile.xlsx'; 

data sheet; 
    set xl.'Sheet1$'n; 
run; 

libname xl clear; 

这将设置您的Excel工作簿,就像数据库一样,工作表直接像表一样引用。我应该注意到我的设置是使用64位Excel的64位SAS 9.4;这是我的理解,例如,如果您有64位SAS和32位Excel,则此方法可能无法按预期工作。

1

我解决了一个类似的问题,在SAS 9.2 导入两个笔划,一个探索表和一个提取数据。

这是我在那里做的一般化,但是请原谅我张贴的来源我没有测试:我的电脑没有安装SAS。 让我们asume您的数据可能看起来像这样(当保存为制表符分隔的文件):

  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开始。让我们假设我们知道以未知的顺序查找列“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_th观测来自在Excel中Ñ + 1条线,因为第一个Excel行被解释为标题。

要计算rangeLeft和rangeRight,我们必须找到相对位置范围左columen我们将阅读和翻译成字母

现在我们在相关资料只读;

/** 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并进行更正,请随时测试此代码。