使用从SAS数据集创建的格式

使用从SAS数据集创建的格式,sas,proc-format,Sas,Proc Format,我创建了如下格式 data formatset; input fmtname $ start $ end $ label $; datalines; $test region1 region3 zone1 $test region4 region5 zone2 $test region6 region7 zone3 ; run; proc format library = work.formats cntlin = work.formatset; run; quit;

我创建了如下格式

data formatset;
    input fmtname $ start $ end $ label $;
    datalines;
$test region1 region3 zone1
$test region4 region5 zone2
$test region6 region7 zone3
;
run;

proc format library = work.formats
    cntlin = work.formatset;
run;
quit;
问题:我将使用变量
region
创建新的数据线数据。我想有一个新属性
区域
,它使用
$test格式。

data output;
    input region $;
    format zone $test.;
    zone = region;
    datalines;
region1
region2
region3
region4
region5
region6
region7
region8
;
run;

使用格式时需要指定宽度,以确保从
区域
变量中读取足够的字符。尝试
格式化区域$test7在第二个数据步骤中


如果未指定宽度,SAS默认为为该格式定义的任何显示值的最大长度。然后,在查找要显示的格式化值时,它将从格式化变量中仅读取那么多字符(在您的示例中为5),如果格式中没有为这5个字符指定值,则会逐字显示。

使用格式时,需要指定宽度,以确保从
区域
变量中读取足够的字符。尝试
格式化区域$test7在第二个数据步骤中

如果未指定宽度,SAS默认为为该格式定义的任何显示值的最大长度。然后,在查找要显示的格式化值时,它将从格式化变量中只读取那么多字符(在您的示例中为5),如果格式中没有为这5个字符指定值,则会逐字显示它们。

使用格式时出现了什么问题 使用
格式区域$test,您创建了一个内部长度为$5(五个字符)的变量
区域
。为了证明这一点,跑吧

proc contents data=output;
run;
zone=region
区域
的值分配给
区域
,然后将其截断为5个字符。标签仅在打印或列出数据时应用。此时,变量
区域
包含文本“regio”,该文本不在
开始
结束
范围内,因此不会被转换

使用格式时如何解决此问题 解决此问题的一种方法是,在为
zone
指定值时,应用已存在的格式,写入
zone=put(region$test)

另一种是用
length zone$7明确指定zone的存储长度format zone$test同时执行这两项操作就像另一个答案所建议的那样

为什么这种格式会这样 当您使用
cntlin
proc format
中创建字符格式时,它将接收最大标签长度,即5个字符。此长度是使用该格式存储的变量的字符数。 你可以看到,如果你跑

proc format library = work.formats
    cntlin = work.formatset;
run;
这的确不合逻辑,更糟糕的是:您不能通过在
cntlin
数据集中指定长度来改变这一点

如何在格式本身中解决它 只需指定格式应显示8字节长的任何值:

data formatset;
    input fmtname $ start $ end $ label $;
    datalines;
$test region1 region3 zone1
$test region4 region5 zone2
$test region6 region7 zone3
$test _dummy_ _dummy_ 1234567
;
run;
使用格式时出现了什么问题 使用
格式区域$test,您创建了一个内部长度为$5(五个字符)的变量
区域
。为了证明这一点,跑吧

proc contents data=output;
run;
zone=region
区域
的值分配给
区域
,然后将其截断为5个字符。标签仅在打印或列出数据时应用。此时,变量
区域
包含文本“regio”,该文本不在
开始
结束
范围内,因此不会被转换

使用格式时如何解决此问题 解决此问题的一种方法是,在为
zone
指定值时,应用已存在的格式,写入
zone=put(region$test)

另一种是用
length zone$7明确指定zone的存储长度format zone$test同时执行这两项操作就像另一个答案所建议的那样

为什么这种格式会这样 当您使用
cntlin
proc format
中创建字符格式时,它将接收最大标签长度,即5个字符。此长度是使用该格式存储的变量的字符数。 你可以看到,如果你跑

proc format library = work.formats
    cntlin = work.formatset;
run;
这的确不合逻辑,更糟糕的是:您不能通过在
cntlin
数据集中指定长度来改变这一点

如何在格式本身中解决它 只需指定格式应显示8字节长的任何值:

data formatset;
    input fmtname $ start $ end $ label $;
    datalines;
$test region1 region3 zone1
$test region4 region5 zone2
$test region6 region7 zone3
$test _dummy_ _dummy_ 1234567
;
run;

问题是,在为变量区域指定格式之前,没有定义变量区域。因此,SAS使用指定格式的默认长度来定义变量区域。您可以通过将FORMAT语句移动到赋值语句之后来解决此问题。然后,SAS将假定分区的长度应与区域的长度相同

但真正的解决方案是在使用变量或附加格式之前定义变量

data output;
  length region $8 zone $8 ;
  input region;
  zone = region;
  format zone $test.;
cards ;
...
如果希望ZONE的值是$TEST所指定的值。format将显示,然后在赋值语句中使用PUT()函数,而不是将format附加到变量

zone = put(region,$test.);

问题是,在为变量区域指定格式之前,没有定义变量区域。因此,SAS使用指定格式的默认长度来定义变量区域。您可以通过将FORMAT语句移动到赋值语句之后来解决此问题。然后,SAS将假定分区的长度应与区域的长度相同

但真正的解决方案是在使用变量或附加格式之前定义变量

data output;
  length region $8 zone $8 ;
  input region;
  zone = region;
  format zone $test.;
cards ;
...
如果希望ZONE的值是$TEST所指定的值。format将显示,然后在赋值语句中使用PUT()函数,而不是将format附加到变量

zone = put(region,$test.);