【问题标题】:SAS Numeric Informat vs LengthSAS 数字信息与长度
【发布时间】:2018-05-17 09:02:32
【问题描述】:

我正在尝试确定 SAS 如何读取 length 语句,然后是 informat 语句。我可能会产生误解,但我的印象是数字变量的 informat 语句是这样工作的:

informat number 5.;

这将为变量number 提供informat 5,允许5 个数字填充它。例如。 12345

但是,当我运行以下程序时,我有一个包含 9 位数字的数字 987654321,其长度适合数字 6,这将代表所有数字,直到 137,438,953,472

问:长度语句是否“覆盖”informat 语句并允许所有 9 位数字填充变量 number?如何将所有 9 位数字都放入变量 number 中,informat 为 5.?

data tst;
input number;
length number 6;
informat number 5.;
datalines;
987654321
;
run;

proc print data=tst;
run;

基于此 SAS 文档: http://support.sas.com/documentation/cdl/en/lrdict/64316/HTML/default/viewer.htm#a000199348.htm

w 指定输入字段的宽度。范围:1-32

informat w.d 似乎可以像我最初描述的那样工作,并且不允许所有 9 位数字都填充 数字

【问题讨论】:

  • 嗨 - 这是一个很好的问题,感谢您提出问题并在问题中提供如此具体的细节。像这样的问题很高兴回答!
  • @Joe 没问题。我真的对此感到困惑。过去我使用信息没有问题,因为我会以适当的长度完成informat number 9.。我遇到了这个并且被难住了。令我难以置信的是输出数据是正确的。

标签: sas informat


【解决方案1】:

因为您使用的是列表模式输入。在这种情况下,SAS 会读取下一个单词,不管它有多长。基本上在列表模式输入中(包括在input 语句中指定的信息之前使用: 修饰符时)信息的宽度被忽略。

除了在 SAS 数据集中创建元数据外,将 5.$10. 等信息附加到变量没有太大价值。

  • SAS 不需要他们了解如何将文本转换为值,这与 date. 等信息不同。
  • 在列表模式下,它会忽略宽度部分。
  • 在格式化输入中,宽度很重要,您必须在INPUT 语句本身中指定信息。

【讨论】:

  • 你的意思是输入语句本身的informat吗?
  • 另外,可以肯定地说,列表输入将读取一个没有信息(或长度语句)的字符变量,直到长度为 8?
  • @DukeLuke List 输入忽略宽度目的的信息,除非它正在创建变量,在这种情况下信息定义长度。它将读取到定义的长度,如果以前从未定义过,则为 8。
  • 最初的问题是变量的类型和长度已经定义的情况。如果对变量的第一次引用包括信息规范,SAS 如何猜测使用什么类型和长度的副作用可以在另一个问题中讨论。
【解决方案2】:

首先:length 不会覆盖或影响信息或读入。 length 仅描述了用于存储数字的字节数,仅此而已。

对于数值变量,信息的工作方式并不直观。我不知道为什么 - 但他们不知道。

请参阅list input documentation 中的此引用:

对于字符变量,此格式修饰符从下一个非空白列读取值,直到指针到达下一个空白列、变量的定义长度或数据行的末尾,以先到者为准。对于数值变量,此格式修饰符从下一个非空白列读取值,直到指针到达下一个空白列或数据行末尾,以先到者为准。

他们确实在一定程度上听取了信息 - 在此处添加 .2 ,您将获得强制小数 - 但他们不听关于要读取多长时间的值。我是不知道为什么;直觉上他们应该这样做,但事实并非如此。

这里是字符变量 - 他们尊重长度但也忽略信息:

data tst;
length number $9;
informat number $5.;
input number;
datalines;
987654321
;
run;

proc print data=tst;
run;

虽然您确实需要将信息放在输入语句之前(以及数字变量的长度)。

更多详情请访问documentation page for INFORMAT

当您使用 INFORMAT 语句分配信息时,SAS 如何处理变量

使用 INFORMAT 语句与变量关联的信息的行为类似于用于修改后的列表输入的信息。 SAS 使用列表输入的扫描功能读取变量,但应用信息。

在修改后的列表输入中,SAS 不使用信息中 w 的值来指定外部文件中的列位置或输入字段宽度 在信息中使用 w 的值来指定以前未定义的字符变量的长度 忽略数字信息中 w 的值 以与通常对数字信息相同的方式在信息中使用 d 的值 除非您在 INFILE 语句中使用 DLM= 或 DLMSTR= 选项规范更改它们的状态,否则将作为输入数据嵌入的空白视为分隔符。

这更清楚地表明 SAS 忽略了w 的值。

【讨论】:

  • SAS 不会区别对待数字和字符。我认为混淆在于如果目标字符变量太短,那么只有适合的字节数被存储,其余的基本上被忽略。那就是光标移过下一个分隔符。
  • @Tom 是的,谢谢,我的意思是在我阅读完其余信息并忘记 - 修复后删除它!
【解决方案3】:

变量的长度定义了值存储到磁盘时占用的空间量。 注意:在运行 DATA 步期间,所有数字都是双精度的,长度小于 8 的截断只发生在输出媒体期间。

informat 是一个独立于length 的概念。 Informat 定义了如何将传入的值表示形式解释为存储为 SAS 数值。传入的值表示将是必须处理的文本;无论是读取文件的 INPUT 语句、处理输入值的 VIEWTABLE 字段编辑、EG 网格单元格编辑等...

格式同样是一个独立的概念,它定义了 SAS 如何为输出呈现数值;无论是 PUT 语句、VIEWTABLE 行渲染、PROC 输出中的放置、EG 网格单元等...

说明

现在已经不碍事了,当在 INPUT 语句中明确声明时,该信息得到尊重:

data _null_;
  attrib number length=6 informat=5.;
  input number 5.;
  put 'NOTE: ' number=;
  datalines;
987654321
run;
===== LOG ===== 
NOTE: number=98765

而且,正如您所质疑的那样,未应用与信息相关的变量,未说明明确的数字信息

data _null_;
  attrib number length=6 informat=5.;
  input number;
  put 'NOTE: ' number=;
datalines;
987654321
run;
===== LOG =====
NOTE: number=987654321

所以第一个是指定格式的 LIST 输入,第二个是 简单 LIST 输入(因为没有指定格式)。

简单的列表输入将接受一些大得离谱的数据,结果值虽然不是尾端精确,但将处于正确的指数水平。

data _null_;
  attrib number length=6 informat=5.;
  input number;
  put 'NOTE: ' number= ;
datalines;
123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
run;
===== LOG =====
NOTE: number=1.2345679E89

INPUT Statement, List 的文档是怎么说的?当然,在没有指明时使用声明为 informat 的变量

简单的列表输入

简单的列表输入对数据类型设置了几个限制, INPUT 语句可以读取:

• 默认情况下,必须至少用一个空格分隔输入值。利用 INFILE 语句中的 DLM= 或 DLMSTR= 选项或 DSD 选项 指定除空白以外的分隔符。

• 用句点表示每个缺失值,而不是空格或两个 相邻的分隔符。

• 字符输入值不能超过 8 个字节,除非 在较早的 LENGTH、ATTRIB 或 信息声明。

• 字符值不能包含嵌入的空格,除非您更改 分隔符。

• 数据必须采用标准数字或字符格式。 (脚注 1)

脚注 1:有关标准和非标准数据值的信息,请参阅 SAS 语言参考:概念。 (我的大声笑)

“SAS 变量属性”状态的概念

信息

指的是 SAS 在读取数据值时使用的指令。 如果 没有指定信息,默认信息是 w.d 用于数字 变量和$w。对于字符变量。您可以分配 SAS 向 INFORMAT 或 ATTRIB 语句中的变量提供信息。你可以 使用 FORMAT 过程为变量创建自己的信息。

(我的粗体字)

显然没有明确的默认值,例如 32. 或 best32。因为超过 32 位的值将被正确输入。

那么文档是否解释了一些事情?是的,嗯,有点。有什么收获:

  • 在简单列表输入期间继承其信息的数值变量的人类直觉实际实现的行为不一致
    • 现有 SAS 代码的构造数量意味着实现这种直觉的更改是极不可能的
  • 简单的陈述可能涉及大量概念和广泛的文档
  • 可能的变化是文档将更新以更明确地说明简单列表输入警告

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-20
    • 1970-01-01
    • 2019-12-17
    • 1970-01-01
    相关资源
    最近更新 更多