将数据读入 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_来读取每个变量。 “困难”部分是如何阅读诊所名称(因为它包含嵌入的空白)。如果诊所并不总是有那个双空白,您仍然可以通过substr
、index
和/或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 对齐并启用水平滚动