SAS从一行中读取多条记录而无需换行CRLF
Posted
技术标签:
【中文标题】SAS从一行中读取多条记录而无需换行CRLF【英文标题】:SAS Reading multiple records from one line without Line Feed CRLF 【发布时间】:2014-01-16 01:16:19 【问题描述】:我只有 1 行没有换行(CRLF CRLF),换行是一个 4 个字符的字符串,在这个例子中是“@A$3”我现在不需要 dlm,我需要从一个外部文件(/files/Example.txt)
JOSH 30JUL1984 1011 SPANISH@A$3RACHEL 29OCT1986 1013 MATH@A$3JOHNATHAN 05JAN1985 1015 chemistry
我需要将此行分成3行:
JOSH 30JUL1984 1011 SPANISH
RACHEL 29OCT1986 1013 MATH
JOHNATHAN 05JAN1985 1015 chemistry
我如何在 SAS 中做到这一点?
*已添加:您的解决方案正在使用此示例,但我有一个问题,包含超过该行允许的最大长度(32,767 字节)的行,
例如,上述练习中的这一行包含 5,000 条记录。
有可能吗?
【问题讨论】:
如果您只是想从一行文本中读取多条记录,请将“@@”附加到“输入”行的末尾,例如:input column1 255。@ @; 【参考方案1】:在infile
语句中使用DLMSTR=
选项——这将指定“@A$3”作为分隔符。然后在输入语句上使用@@
告诉 SAS 在同一行查找更多记录。
data test;
infile "/files/Example.txt" dsd dlmstr='@A$3';
informat var $255.;
input var $ @@;
run;
通过您的示例,您将获得一个包含 3 条记录的数据集,其中 1 个变量包含您要查找的字符串。
根据需要调整 var 的长度。
【讨论】:
我们遇到了DLMSTR=
的问题,它没有将@A$3@A$3
识别为缺失值。那是在 SAS 9.2 中,现在可能已经修复了。
@DejanPeretin 我也曾想过使用DLMSTR=
来指定多字符分隔符,但它可能不适用于所有版本。因此,需要使用单字符定界符的替代转换方法。我认为 DomPazz 的 DLMSTR=
应该适用于 SAS 9.2 及更高版本,因为它是在 9.2 中引入的,但对于 9.1.3 及更早版本,它会作为错误返回。
发现:如果文件中有连续的分隔符字符串指示缺失值,则 DLMSTR= 选项将无法正确读取文件,直到 SAS 9.3。来源:support.sas.com/kb/33/385.html【参考方案2】:
你可以这样做:
先将文件导入为单行(一定要调整长度):
DATA WORK.IMPORTED_DATA;
INFILE "/files/Example.txt" TRUNCOVER;
LENGTH Column1 $ 255;
INPUT @1 Column1 $255.;
RUN;
然后使用数据步骤将导入的数据解析为变量:
data result (keep=var1-var4);
set WORK.IMPORTED_DATA;
delim = '@A$3';
end = 1;
begin = 1;
do while (end > 0);
end = find(Column1, delim, begin);
row = substr(Column1, begin, end - begin);
var1 = scan(row, 1);
var2 = scan(row, 2);
var3 = scan(row, 3);
var4 = scan(row, 4);
begin = end + length(delim);
output;
end;
run;
【讨论】:
【参考方案3】:通过将@A$3
视为多字符分隔符,在数据步骤中尝试此操作:
data want (keep=subject);
infile 'C:\sasdata\test.txt';
input;
length line $4500 subject $80;
line=tranwrd(_infile_,"@A$3",'!');
do i=1 by 1 while (scan(line,i,'!') ^= ' ');
subject=scan(line,i,'!');
output;
end;
run;
_infile_
给出在data
步骤中正在读取的当前行。我将多字符分隔符@A$2
转换为单字符分隔符。 tranwrd()
可以替换字符串中的子字符串。然后在scan()
函数中使用分隔符。
此外,如果您想将值分解为单独的变量,只需再扫描一些即可。例如。将B = scan(subject,2);
之类的内容放入do
循环和data want (keep= A B C D);
。干杯。
【讨论】:
以上是关于SAS从一行中读取多条记录而无需换行CRLF的主要内容,如果未能解决你的问题,请参考以下文章