正在将数据读入SAS,列未对齐

正在将数据读入SAS,列未对齐,sas,Sas,我有一个如下所示的数据文件: 001 Mayo Clinic 120 78 7 15 Patient has had a persistent cough for 3 weeks 023 Mayo Clinic 157 72 10 2 Patient complained of ear ache 064 HMC 201 59 . . Patient left against medical advice 003 HMC 166 58 8 15 Patient placed on

我有一个如下所示的数据文件:

001 Mayo Clinic  120 78 7 15 
Patient has had a persistent cough for 3 weeks
023 Mayo Clinic  157 72 10 2 
Patient complained of ear ache
064 HMC  201 59 . . 
Patient left against medical advice
003 HMC  166 58 8 15 
Patient placed on beta-blockers on 7/1/2006
我发现把这个读入SAS的任务基本上是不可能的。不,在这种情况下,重新格式化数据文件是不可能的。让我来解释一下你在这里看到的是什么:

每个主题有两行数据。第一行是-

受试者编号/诊所/wt/hr/dx/sx (不要担心数字的含义,那无关紧要)

第二行是文本,它基本上是一个注释,包含关于主题的额外信息,该主题的数据在前一行中列出。因此,这些行:

001 Mayo Clinic  120 78 7 15 
Patient has had a persistent cough for 3 weeks
只针对一个主题。受试者001。这些需要成为SAS数据集中的一行。我完全不知所措;由于诊所名称的长度不同,并且数字列没有对齐,因此我不知道如何让SAS读取此内容。这是我能得到的最接近的结果:

data ClinData;
    infile "&wdir.clinic_data.txt";
    retain patno clinic weight hr dx sx exinfo;
    input patno clinic $1. @;
    if clinic='M' then
        input patno @5 clinic $11. weight hr dx sx / @1 exinfo $30.;
    else if clinic='H' then
        input patno @5 clinic $3. weight hr dx sx / @1 exinfo $30.;
    run;
此文件打印为:

所有数值都在正确的位置

然而,这有几个问题

首先,主题编号(“patno”)总是显示为缺少的值。为什么?

第二,诊所仅以其第一个字母“M”或“H”表示。我无法让SAS根据它所在的诊所更改诊所变量的长度

第三,变量“exinfo”包含关于患者的注释。但是,我无法让SAS包含整个产品线。我能得到的最高值是大约30个字符,在格式失控之前


有什么帮助吗?SAS文档对于这种类型的输入非常糟糕。没有一个例子真正符合我的需要,它也没有充分解释如何使用一些选项。我知道我需要使用列/行指针;但问题是,行与行之间的列不一致。因此,无论我使用哪种指针格式,仍然会有一些行显示不正确。

您以奇怪的方式混合输入类型,无法正确读取这些内容

您的诊所长度为1,因为您将其作为一个字符输入,该字符将其定义为1。不要这样做-如果需要,使用一次性变量-并将其长度定义为更长的长度

我建议采用如下方法。使用infle(输入过程中创建的包含一行数据的自动变量)比单独使用输入技术更容易。你的数据很简单;如果它比您提供的更复杂(比如您有更多的诊所),正则表达式或其他逻辑可能有助于进一步实现这一点,而infle将更容易解析。还有ANYDIGIT和NODIGIT以及类似的函数,还有COMPRESS,这可能会有所帮助

data want;
length clinic $12;
input 
@1 patid 3. @;  *hold input so _infile_ exists and we can play with it.  Might as well read in patid here.;
array numvars weight hr dx sx; *we are going to read this in via array;
do _t = 4 to 1 by -1;  *we are going through the string in backwards order;
 numvars[_t] = scan(_infile_,(_t-5),' '); *(_t-5) is giving us 4 -> -1 3 -> -2 etc.- I include space explicitly here as I think period otherwise might count which is bad;
end;
clinic = scan(_infile_,2); *start out using the 2nd word;
if scan(_infile_,3) = 'Clinic' then clinic=catx(' ',clinic,scan(_infile_,3)); *then maybe add the third word.  Here you could also check if compress(scan(_infile_,3),,'ka') is not missing;
input;
input @1 exinfo $50.;
put _all_;
datalines;
001 Mayo Clinic  120 78 7 15 
Patient has had a persistent cough for 3 weeks
023 Mayo Clinic  157 72 10 2 
Patient complained of ear ache
064 HMC  201 59 . . 
Patient left against medical advice
003 HMC  166 58 8 15 
Patient placed on beta-blockers on 7/1/2006
;;;;
run;

SAS中没有什么是不可能的。查看您的样本数据,我注意到您的诊所名称后有两个空格,您的患者编号始终为三个字符。如果这总是正确的,那么您可以利用这一点:

data want;
  length patno $3 clinic $20 weight hr dx sx 8 exinfo $80;
  input;
  patno  = scan(_infile_,1,' ');
  clinic = substr(_infile_,5,index(_infile_,'  ')-5);
  weight = input(scan(_infile_,-4,' '),8.);
  hr     = input(scan(_infile_,-3,' '),8.);
  dx     = input(scan(_infile_,-2,' '),8.);
  sx     = input(scan(_infile_,-1,' '),8.);
  input exinfo $80.;

datalines;
001 Mayo Clinic  120 78 7 15 
Patient has had a persistent cough for 3 weeks
023 Mayo Clinic  157 72 10 2 
Patient complained of ear ache
064 HMC  201 59 . . 
Patient left against medical advice
003 HMC  166 58 8 15 
Patient placed on beta-blockers on 7/1/2006
run;
基本上,这是解析自动变量\u infle\u来读取每个变量。“难”的部分是如何阅读诊所名称(因为它包含插入的空格)。如果诊所不总是有双空白,您仍然可以通过
substr
index
和/或
scan
功能的其他操作来完成。如果是这样的话,我就留给你了


此外,在创建新数据集时,始终使用length语句定义变量,以确保它们具有正确的长度,尤其是对于字符变量。

您遇到的大多数问题都是由于您明确声明的长度造成的。例如,Clinic在初始输入语句中定义为$1,您不能在第二个输入行中尝试修改该事实后的长度

这会让你更接近你想要的东西:

data ClinData(drop=s varlen);
  retain patno clinic weight hr dx sx; 

  input patno clinic $30. @;
    clinic=compress(clinic,,'ka');
    s=length(clinic)+4+2;
   input @s weight hr dx sx /@; 
     varlen=length(_infile_); 
    input  @1 exinfo $varying256. varlen;

datalines4;
001 Mayo Clinic  120 78 7 15 
Patient has had a persistent cough for 3 weeks
023 Mayo Clinic  157 72 10 2 
Patient complained of ear ache
064 HMC  201 59 . . 
Patient left against medical advice
003 HMC  166 58 8 15 
Patient placed on beta-blockers on 7/1/2006
;;;;
run; 
proc print data=ClinData; run;

哈,是的,我不是说在SAS是不可能的,而是说没有帮助我是不可能的。我知道这是可能的。无论如何,谢谢你的帮助!直到今天晚些时候,我才能再次查看该数据集,因此我将在下午尝试此操作,如果有任何问题,请告诉您。谢谢您的帮助!我要到下午晚些时候才能测试出来。如果我有什么困难,我会告诉你的。再次感谢!欢迎我任意设置了clinic和exinfo字段的长度(分别为30美元和256美元)。您可能希望将其调整为较小的长度,尤其是当文件相当大或经常生成时,因为即使字段中包含的最长长度明显较小(即:11和48),文件大小也将表示分配的空间(30和256)。