【问题标题】:SAS Reading multiple records from one line without Line Feed CRLFSAS从一行中读取多条记录而无需换行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。@ @;

标签: import sas linefeed


【解决方案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);。干杯。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-26
      • 1970-01-01
      • 2012-05-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多