很多PROC進口的嘗試失敗後,一般來說,我決定,最好是避免,因爲它有時令人驚訝的結果出現。
您可以改用INFILE命令datastep內:
data input_data;
infile "../../file.txt"
firstobs = 2
dlm = " "
missover
dsd
lrecl = 32767
input
var1 : $char128. /*string field of 128 chars long*/
var2 : best32. /*numbers of all types ints, floats, etc */
...
/*do this for every variable (column) in you .txt file */
;
run;
上面的代碼是或多或少PROC進口做什麼。 proc導入的問題在於它試圖「猜測」正確的選項(如dsd,missover等)和數據類型,它並不總是成功的。您可以在這些選項中找到更多信息here。
例如,missover選項告訴sas如果發現兩個連續的分隔符,該怎麼做。 (這是否應該視爲一個空列,並且在讀取下一個值時將其留空或者只是將下一個可用值拉入?)
當然,上面的代碼在長txt文件的情況下不太實際有很多列,因爲您必須自己輸入每個列標籤的數據類型。
的一種可能的解決方案是:
data headers;
infile "../../file.txt"
firstobs = 1
obs = 1
dlm = "_" /*make sure to here to use a delimiter DIFFERENT from the real one to keep everything in one observation*/
missover
lrecl = 32767
input
whole_line : $char32767.
;
run;
上述步驟創建具有包含所有通過您的分隔符分隔列標題一個觀測的數據集。 現在你可以使用:
proc sql noprint;
select distinct tranwrd(compress(line),","," ") as lineTest length=32767 into: headers from headers length;
quit;
上面的代碼創建了一個宏觀變量調用用空格分隔列名頭文件(即tranwrd()函數基本符合'因爲我平時一起工作取代了「」 csv文件,所以這可能對您沒有必要。一般來說,使用空格作爲分隔符可能不是一個好主意 - 這適用於如果您的字符串字段中包含空格本身,您得到的錯誤實際上可能與此有關)
現在您可以遍歷宏變量而不是逐個寫入列名並逐個輸入:
data inputFile (compress=binary) ;
infile "../../file.txt"
dsd
dlm = ","
lrecl = 32767
firstobs = 2
;
input
%do i=1 %to %words(&headers);
%let currCol = %scan(&headers. , &i.);
&currCol : $char256.
%end;
;
run;
這將創建您想要的數據集,而不用擔心文件結構是否發生了更改(添加或刪除了列),這會使您的代碼更具動態性。當然,這留下了所有值都作爲字符導入的問題。
這絕對是一個問題,但我發現按照需求轉換變量比在輸入語句中逐個輸入每個變量要容易得多。
如果您將使用宏變量和%do循環,請確保將所有代碼包含在宏中,否則循環會給出錯誤。
我希望這有助於!
日誌說什麼?您可以通過點擊屏幕底部的「日誌」選項卡來提交日誌。你確定你的文件在指定的路徑嗎? – LJW
先轉到日誌,它會告訴你確切的原因,沒有這個,它是不可能的調試。 – NEOmen
我的$ 0.02是無法找到您的分隔符或您的文件本身。也許這是標籤不是空間,就像那樣。但絕對張貼整個錯誤消息,不只是一條線。 – Joe