2016-07-06 50 views
0

我在下面的url找到了一個答案。從CSV導入所有列爲字符?在許多變量CSV數據

Import all columns from CSV as character?

但是,對於我的數據,這個宏只導入43個變數,這應該是4126個變量。

我想這個問題可能來自宏觀語法,其中

做,直到(newvar ='「);

但是,我不能解決這個問題。

有人可以教我如何解決它。

我的csv數據可以下載如下dropbox鏈接。

https://www.dropbox.com/s/m01iaqkg5s0tkl2/1771020.csv?dl=0

%macro readme(dsn,fn); 
/* Macro to read all columns of a CSV as character */ 
/* Parameters:          */ 
/* DSN - The name of the SAS data set to create */ 
/* FN - The external file to read (quoted)  */ 
/* Example:          */ 
/* %readme(want, 'c:\temp\tempfile.csv');  */ 
data _null_; 
    infile &fn; 
    input; 
    i = 1; 
    length headers inputstr $200; 
    headers = compress(_infile_,"'"); 
    newvar = scan(headers,1,','); 
    do until (newvar = ' '); 
    inputstr = trim(inputstr) || ' ' || trim(newvar) || ' $'; 
    i + 1; 
    newvar = scan(headers,i,','); 
    end; 
    call symput('inputstr',inputstr); 
    stop; 
run; 

data &dsn; 
    infile &fn firstobs=2 dsd dlm=',' truncover; 
    input &inputstr.; 
run; 
%mend; 
%readme(want, 'c:\temp\tempfile.csv'); 
+0

我不喜歡使用proc導入程序。由於在我的情況下只有很少的觀察和太多的變量,proc導入過程將花費太多時間來識別變量並在3000個變量後截斷變量名稱。 –

回答

1

3000變量的主要問題是可能是線路長度太長。確保在INFILE語句中使用LRECL選項。

您可以忽略變量名稱。

data want ; 
    infile "myfile" dsd firstobs=2 truncover lrecl=1000000 ; 
    length var1-var3000 $200 ; 
    input var1-var3000; 
run; 

或者您可以從第一行讀取名稱並使用它們生成代碼。您可能無法使用宏變量,因爲它們被限制爲65K個字符。從名稱中生成LENGTH語句會更容易。

filename code temp; 
data _null_; 
    file code ; 
    if _n_=1 then put 'LENGTH'; 
    if eof then put ' $200 ;'; 
    infile "myfile" dsd obs=1 lrecl=1000000 end=eof; 
    length name $32 ; 
    input name @@ ; 
    put ' ' name ; 
run; 

然後,您可以在創建表的步驟中使用該LENGTH語句。

data want ; 
    infile "myfile" dsd firstobs=2 truncover lrecl=1000000 ; 
%include code/source2 ; 
    input (_all_) (+0) ; 
run; 

還要確保,因爲你可能會創造比他們需要更長的時間變量,設置壓縮選項。您可以設置系統選項。

options compress=yes; 

或使用數據集選項。

data want (compress=yes); 

如果列標題實際上不是變量名稱,那麼將它們用作標籤。您可以如下更改代碼生成步驟,以生成LENGTH和LABEL語句,以使用通用名稱VAR1,VAR2,...命名變量。

data _null_; 
    file code ; 
    if _n_=1 then put 'LABEL'; 
    if eof then put ';'/'LENGTH VAR1-VAR' N ' $200 ;'; 
    infile "myfile" dsd obs=1 lrecl=1000000 end=eof; 
    length label $256 ; 
    input label @@ ; 
    N+1; 
    put ' VAR' N '=' label :$quote. ; 
run; 
+0

我運行你給的第二個語法。 文件名代碼temp; 但我花了我十分鐘,還沒有完成。 所以我終止了它。 我看起來你提供的從csv數據中讀取名字的方法花費了太多時間。 我們可以有更好的方法嗎? –

+0

問題在於TRUNCOVER選項。我已經刪除它。OBS = 1將使其只讀取一行,因此它不會花很長時間(如果它沒有陷入無限循環!)。 – Tom

+0

當我使用此語法時,發現以下錯誤。 錯誤180-322:語句無效或使用的順序不正確。 它看起來像一些變量名稱,當我們導入它們時有問題。 –