将数据读入 SAS,列未对齐

Posted

技术标签:

【中文标题】将数据读入 SAS,列未对齐【英文标题】:Reading data into SAS, columns not aligned 【发布时间】:2014-03-05 00:06:54 【问题描述】:

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

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;

这打印为:

http://i61.tinypic.com/2uswl90.png

所有数值都在正确的位置。

但是,这有几个问题。

首先,主题编号 ('patno') 始终显示为缺失值。为什么?

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

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

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

【问题讨论】:

【参考方案1】:

在 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;

基本上这是解析自动变量_INFILE_来读取每个变量。 “困难”部分是如何阅读诊所名称(因为它包含嵌入的空白)。如果诊所并不总是有那个双空白,您仍然可以通过substrindex 和/或scan 函数的其他操作来完成。如果是这样,我会留给你的。

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

【讨论】:

哈,是的,我并不是说这在 SAS 中是不可能的,而是说我在没有帮助的情况下是不可能的。我知道这是可能的。无论如何,感谢您的帮助!直到当天晚些时候我才能再次查看该数据集,所以我会在下午尝试这个,如果有任何问题,请告诉您。【参考方案2】:

您遇到的大多数问题都是由于您明确声明的长度。例如 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;

【讨论】:

欢迎。我任意设置了诊所和 exinfo 字段的长度(分别为 30 美元和 256 美元)。您可能希望将它们调整为更小的长度,尤其是在文件相当大或经常构建的情况下,因为文件大小将代表分配的空间(30 和 256),即使该字段中包含的最长长度明显更小(即: 11 和 48)。【参考方案3】:

您以奇怪的方式混合输入类型,导致您无法正确阅读。

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

我推荐如下方法。使用 INFILE(在输入过程中创建的包含一行数据的自动变量)比尝试单独使用输入技术更容易。您的数据非常简单;如果它比你提供的更复杂(例如你有比这更多的诊所),正则表达式或其他逻辑可能会进一步帮助 - infile 将更容易解析。还有 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,列未对齐的主要内容,如果未能解决你的问题,请参考以下文章

标题/数据列未与 jQuery dataTables、bootstrap 2.3.2 对齐并启用水平滚动

移动设备上的列未居中对齐

s-s-rs 报告列未与标题对齐

Bootstrap 页脚列未对齐

obiee 12c rpd 工具实用程序存储库文档到 csv 列未对齐且表示列为空

可水平滚动的 TableView 的右列未完全显示