1

我有一个像这样的 blood.txt 数据集(前 5 个 obs):

1    Female AB Young 7710   7.4  258
2    Male   AB Old   6560   4.7  .
3    Male   A  Young 5690   7.53 184
4    Male   B  Old   6680   6.85 .
5    Male   A  Young .      7.72 187

我使用以下程序来阅读它:

data blood_sum;
infile "/path/blood.txt";
input @1 SubjID $
      @6 Gender $
      @13 BloodType $
      @16 AgeGrp $
      @22 RBC 
      @29 WBC
      @34 Cholesterol ;
run;

但是最后一列“Cholesterol”无法显示;所有值都替换为“。” 我的日志有很多这样的 NOTE 错误:

NOTE: Invalid data for Cholesterol in line 1 34-37.
 RULE:     ----+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0                      

 1   CHAR  1    Female AB Young 7710   7.4  258. 37
     ZONE  3222246666624425676623333222323223330
     NUMR  1000065D1C501209F5E7077100007E400258D
 SubjID=1 Gender=Female BloodType=AB AgeGrp=Young RBC=7710 WBC=7.4 Cholesterol=. _ERROR_=1 

任何人都可以帮忙吗?

4

2 回答 2

2

我猜你是在 UNIX 系统上运行它,但你正在阅读的文件 (blood.txt) 是在 Windows 系统上创建的,并以二进制模式复制到你的系统中。

如果您查看日志,您应该注意到在输入行的最后一个值之后有一个“点”(在第 37 列中)。显示屏的 ZONE 和 NUMR 部分显示该位置的十六进制代码,在本例中为“0D”,它是一个回车符。如果您使用 UNIX 编辑器(如 vi)打开文件,您将看到这些字符表示为^M每行的末尾。

您可以从您收到它的地方下载一个新副本(确保以 TEXT 模式传输文件),也可以将您的副本转换为 UNIX 文本文件。要进行转换,您可以使用如下dos2unix命令:

dos2unix /path/blood.txt /path/blood.txt

请注意,如果您使用相同的名称,它将覆盖原始文件。当然,我假设您有权这样做。

如果由于某种原因无法转换文件,可以使用管道进行转换。换句话说,使用此 FILENAME 语句并将您的 INFILE 语句更改为从文件名中读取:

filename mydata pipe "tr -d '\r' < /path/blood.txt";
data blood_sum;
   infile mydata truncover;
   input @1 SubjID $
         @6 Gender $
        @13 BloodType $
        @16 AgeGrp $
        @22 RBC 
        @29 WBC
        @34 Cholesterol ;
run;

truncover尽管您可能不需要它,但我添加了该选项。如果有兴趣,请在文档中阅读有关它的更多信息。

顺便说一句,这是一个非常常见的错误,每个人都至少发生一次。欢迎来到 StackOverflow。

于 2013-02-16T19:48:39.727 回答
0

对于这个问题,我将给出一个稍微不同的解决方案,我同意 Bob 是由行尾的回车引起的。

您可以使用 infile 上的 TERMSTR 选项控制行的终止字符(通常,对于 Windows,CR/LF 或 '0d'x '0a'x ;对于 Unix,仅 '0a'x 或 LF)。

http://support.sas.com/kb/14/178.html

data blood_sum;
   infile "/path/blood.txt" termstr=CRLF;
   input @1 SubjID $
         @6 Gender $
        @13 BloodType $
        @16 AgeGrp $
        @22 RBC 
        @29 WBC
        @34 Cholesterol ;
run;

顺便说一句,我觉得你的输入法有点混乱。你在这里混合了输入类型,所以你可能并不总是得到一致的结果。事实上,如果您明确指定了格式,这可能永远不会发生!

input
@1 subjid $4.
@6 gender $6.
@13 bloodtype $2.
@16 agegrp $5.
@22 rbc best8.
@29 wbc best4.
@34 Cholesterol 3.
;

然后将从 34-36 读取胆固醇,并且您永远不会让 SAS 尝试将 37 包含在变量中。

于 2013-02-17T02:33:22.420 回答