2016-05-15 71 views
-1

如何使用現有SAS數據集的格式導入SAS中的csv以及如何從此過程創建宏?如何使用預先指定的變量格式編寫從csv文件創建SAS數據集的%宏?

假設我設法從具有方便格式的數據集中的5個csv文件加載數據。現在我定期發佈這些文件的新版本(v2,v3,...),並且我想將數據加載到新數據集中,格式與舊數據集相同。

我該如何編寫一個宏?

+0

請更具體 –

+0

假設有在圖書館5個SAS舊數據集的版本v2和有5個新的CSV與版本V3和任務是導入新的CSV的進入SAS與舊格式(從V2)。這個過程應該以這樣一種方式自動化,即它查找csv的名稱和版本,首先取出它的標題,然後使用舊的sas數據集(v2)的格式並創建新的sas數據集v3。謝謝! – Tarun

+0

我希望我解釋正確。 –

回答

1

一個簡單的方法做,這是

  1. 檢查你現有的數據集與proc contents
  2. proc import
  3. 讀新到的文件中的數據的結構複製所產生的數據的步驟proc import來自日誌文件
  4. 將其修改爲符合所需的結構(格式)
  5. 使用一些宏變量對其進行參數設置
  6. 使宏的這些宏變量參數。

或者一些提示添加到該程序的企業指南中

例如假設proc contents data=mydata; run;給你以及其他信息這

Alphabetic List of Variables and Attributes   
# Variable Type Len 
3 long  Char 50 
1 num   Num  8 
2 short  Char 8 

與此

導入此

num,kort,lang 
4,alfa,A short sentence 
5,beta,And another one 

proc import replace 
    datafile='c:\TEMP\csv_v3.csv' 
    out=myData; 
    format num 8. kort $8. lang $33.; 
run; 

日誌

29   /********************************************************************** 
30   * PRODUCT: SAS 
31   * VERSION: 9.4 
32   * CREATOR: External File Interface 
33   * DATE:  15MAY16 
34   * DESC:  Generated SAS Datastep Code 
35   * TEMPLATE SOURCE: (None Specified.) 
36   ***********************************************************************/ 
37    data WORK.MYDATA ; 
38    %let _EFIERR_ = 0; /* set the ERROR detection macro variable */ 
39    infile 'c:\TEMP\csv_v3.csv' delimiter = ',' MISSOVER DSD lrecl=32767 firstobs=2 ; 
40    informat num best32. ; 
41    informat kort $4. ; 
42    informat lang $16. ; 
43    format num best12. ; 
44    format kort $4. ; 
45    format lang $16. ; 
46    input 
47       num 
48       kort $ 
49       lang $ 
50    ; 
51    if _ERROR_ then call symputx('_EFIERR_',1); /* set ERROR detection macro variable */ 
52    run; 

您可以自定義爲

%macro importMyData(csvName); 
data WORK.MYDATA; 
/* The first dot in &csvName..csv below closes the macro variable name, 
    so you need the second too */ 
    infile "c:\TEMP\&csvName..csv" 
     delimiter = ',' MISSOVER DSD lrecl=32767 firstobs=2 ; 
/* Note the firstobs option, which skips the headers! */ 

/* Set the formats accordign to the output of proc contents */ 
    format num 8. ; 
    format kort $8. ; 
    format lang $50. ; 

/* Potentially you need to set a few informats too 
    I left one as an example */ 
    informat num best32. ; 

    input 
      num 
      kort $ 
      lang $ 
    ; 
run; 
%mend; 
%importMyData(csv_v3.csv); 
+0

謝謝Dirk給我一個解決方案。 我需要一個宏,因爲可以有n個csv,所以不需要編輯每個csv的代碼。代碼本身應該處理從sas數據集的prev版本中獲取的格式,並將其用於proc import或infile語句中以獲得新的sas數據集。 – Tarun

+0

使用'proc contents noprint date = myData out = myStructure;'您可以在數據集中獲得相同的信息。從這裏,你可以自動構建一個數據步驟,以適當的輸入在csv中讀取,但可能需要將其調整爲csv中使用的格式。那是你需要的嗎? –

1

因此,如果新的CSV文件的結構的現有數據集的結構相匹配,那麼你應該能夠讀取,因爲這有一個這樣簡單的程序:

data new ; 
    if 0 then set old ; 
    infile "new.csv" dsd firstobs=2 truncover ; 
    input (_all_) (+0); 
run; 

你可以將它轉換爲一個宏由f首先用宏變量替換輸入數據集,模型數據集和輸出數據集。

%macro readcsv(infile,out,model); 
data &out; 
    if 0 then set &model; 
    infile "&infile" dsd firstobs=2 truncover ; 
    input (_all_) (+0); 
run; 
%mend readcsv; 

所以對宏調用可能看起來像:

%readcsv(infile=file1_v2.csv,out=mylib.file1_v2,model=mylib.file1) 

麻煩會來,如果輸入CSV文件中不遵循模型。所以如果列的順序錯誤,那麼數據將被讀入錯誤的字段。此外,您還需要確保將INFORMAT與變量相關聯,如日期和時間值,這些變量在模型數據集中將需要它們。

您可以通過將輸入語句中的_all_替換爲CSV文件中的名稱列表來修復列順序問題。但是這需要名稱與模型變量名稱匹配。以前的版本只是要求列的順序與模型匹配。

%macro readcsv2(infile,out,model); 
%local names ; 
data _null_; 
    infile "&infile" obs=1; 
    input; 
    call symputx('names',translate(_infile_,' ',',')); 
run; 
data &out; 
    if 0 then set &model; 
    infile "&infile" dsd firstobs=2 truncover ; 
    input (&names) (+0); 
run; 
%mend readcsv2; 
+0

這是一個有趣的解決方案。你是否願意詳細說明這將如何工作? –

+1

我擴大了答案。 – Tom