很多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