sas

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

SAS Language

SAS语言

Write idiomatic, production-quality SAS code. This skill covers the SAS language itself, independent of any framework.
编写符合规范、可用于生产环境的SAS代码。本技能仅涵盖SAS语言本身,与任何框架无关。

Scope

适用范围

  • DATA step programming (SET/MERGE/BY, RETAIN, arrays, DO loops, hash objects, first./last. processing)
  • PROC SQL (joins, subqueries, views, pass-through with CONNECT TO)
  • Macro language (%macro/%mend, macro variables, %local/%global, conditional %IF logic, quoting functions %STR/%NRSTR/%BQUOTE, CALL SYMPUTX)
  • Common PROCs: SORT, MEANS/SUMMARY, FREQ, TRANSPOSE, REPORT, PRINT, CONTENTS, DATASETS, FORMAT, IMPORT/EXPORT
  • Formats and informats (user-defined via PROC FORMAT, picture formats)
  • ODS output (HTML, PDF, RTF, Excel, OUTPUT destination)
  • File I/O: LIBNAME, FILENAME, INFILE/INPUT, FILE/PUT
  • DATA step编程(SET/MERGE/BY、RETAIN、数组、DO循环、哈希对象、first./last.处理)
  • PROC SQL(连接、子查询、视图、使用CONNECT TO的直通查询)
  • 宏语言(%macro/%mend、宏变量、%local/%global、条件%IF逻辑、引用函数%STR/%NRSTR/%BQUOTE、CALL SYMPUTX)
  • 常用PROC过程:SORT、MEANS/SUMMARY、FREQ、TRANSPOSE、REPORT、PRINT、CONTENTS、DATASETS、FORMAT、IMPORT/EXPORT
  • 格式与输入格式(通过PROC FORMAT自定义、图片格式)
  • ODS输出(HTML、PDF、RTF、Excel、OUTPUT目标)
  • 文件I/O:LIBNAME、FILENAME、INFILE/INPUT、FILE/PUT

Non-negotiable: no WARNINGs

不可妥协:无WARNING信息

Generated SAS code must run cleanly — zero WARNINGs (and zero ERRORs) in the log. Treat every
WARNING:
as a defect: uninitialized variables, implicit type conversions, truncation notes that should be warnings, "no observations", unresolved macro references, etc. If a warning is truly unavoidable, suppress it deliberately (e.g. an explicit option) and comment why. Likewise avoid superfluous NOTEs where reasonable.
生成的SAS代码必须能干净运行——日志中零WARNING(且零ERROR)。将每一条
WARNING:
视为缺陷:未初始化变量、隐式类型转换、应作为警告的截断提示、“无观测值”、未解析的宏引用等。若警告确实无法避免,需主动抑制(例如使用显式选项)并注释原因。同样,在合理情况下避免多余的NOTE信息。

Style rules

风格规则

These follow the @sasjs/core coding standards — apply them to all SAS code:
  • One statement per line; indentation = 2 spaces, no tabs, no trailing whitespace
  • Lines no longer than 80 characters; unix (LF) line endings; UTF-8
  • Avoid non-ASCII / special characters entirely — maximum compatibility across SAS installations and encodings
  • Always end steps with
    run;
    ; for
    proc sql
    (and CAS-connected procs)
    quit;
    is essential to avoid
    WARNING: You cannot disconnect or terminate session ...
    on Viya
  • All dataset references must be 2-level (
    work.blah
    , not
    blah
    ) — protects against
    DATASTMTCHK=ALLKEYWORDS
    and an active
    USER
    library
  • Explicit
    length
    /
    attrib
    for character variables rather than relying on defaults (avoids implicit length=8 truncation)
  • Use literal suffixes for clarity (
    '01JAN2020'd
    ,
    '12:30't
    )
  • Prefer
    proc sort
    with
    nodupkey
    over manual dedup logic
  • Macros:
    • Define with parentheses, even with no parameters:
      %macro x();
      not
      %macro x;
    • Closing
      %mend;
      must repeat the macro name
    • Macro calls are not terminated with a semicolon:
      %my_macro()
      not
      %my_macro();
    • Mandatory parameters positional; optional parameters keyword (
      var=
      ) style
    • Macro names lowercase, verb-noun convention
    • Macro variables without trailing dot (
      &var
      not
      &var.
      ) unless needed to prevent incorrect resolution
    • ALL macro variables must be
      %local
      unless deliberately global (globals should use an application prefix to avoid collisions); use
      call symputx
      (not
      symput
      ) in DATA steps
    • Comment with
      /* */
      inside macros (asterisk comments are compiled into the macro)
    • Guard macro logic with
      %length(&var)=0
      checks rather than
      &var=
      (empty comparisons are unsafe)
  • Avoid naming collisions: use
    %sysfunc
    -/
    &syslast
    -based work tables (e.g.
    data &output; set &syslast; run;
    ) rather than hard-coded names
以下遵循@sasjs/core编码标准——适用于所有SAS代码:
  • 一行一条语句;缩进为2个空格,不使用制表符,无尾随空格
  • 行长度不超过80字符;使用Unix(LF)换行符;UTF-8编码
  • 完全避免非ASCII/特殊字符——确保在不同SAS安装环境和编码下的最大兼容性
  • 所有步骤必须以
    run;
    结尾;对于
    proc sql
    (及连接CAS的过程),必须使用
    quit;
    以避免Viya上出现
    WARNING: You cannot disconnect or terminate session ...
    警告
  • 所有数据集引用必须使用两级命名(
    work.blah
    ,而非
    blah
    )——防止
    DATASTMTCHK=ALLKEYWORDS
    和活跃
    USER
    库导致的问题
  • 字符变量需显式定义
    length
    /
    attrib
    ,而非依赖默认设置(避免隐式长度为8的截断问题)
  • 使用字面量后缀增强清晰度(
    '01JAN2020'd
    '12:30't
  • 优先使用带
    nodupkey
    proc sort
    而非手动去重逻辑
  • 宏相关规则:
    • 定义宏时需加括号,即使无参数:
      %macro x();
      而非
      %macro x;
    • 结束宏的
      %mend;
      必须重复宏名称
    • 宏调用无需以分号结尾:
      %my_macro()
      而非
      %my_macro();
    • 必填参数使用位置式;可选参数使用关键字(
      var=
      )风格
    • 宏名称使用小写,遵循“动词-名词”命名规范
    • 宏变量无需尾随点号(
      &var
      而非
      &var.
      ),除非需要避免解析错误
    • 所有宏变量必须定义为
      %local
      ,除非特意设为全局变量(全局变量应使用应用前缀以避免冲突);在DATA step中使用
      call symputx
      (而非
      symput
    • 宏内部使用
      /* */
      注释(星号注释会被编译到宏中)
    • 使用
      %length(&var)=0
      检查宏逻辑,而非
      &var=
      (空值比较不安全)
  • 避免命名冲突:使用基于
    %sysfunc
    /
    &syslast
    的临时表(例如
    data &output; set &syslast; run;
    )而非硬编码名称

Portability awareness

可移植性注意事项

  • Note when code differs between SAS 9.4 and Viya (e.g. CAS actions vs procs,
    proc casutil
    for sashdat loading, no X command on locked-down servers)
  • Avoid hard-coded physical paths and engine-specific options unless asked
  • 注意SAS 9.4与Viya之间的代码差异(例如CAS动作与过程、使用
    proc casutil
    加载sashdat文件、锁定服务器上无X命令)
  • 除非特别要求,否则避免硬编码物理路径和引擎特定选项

Common pitfalls to flag when reviewing

代码审查时需标记的常见陷阱

  • Unintended many-to-many MERGEs
  • Automatic variable
    _ERROR_
    / implicit RETAIN surprises
  • Macro timing issues: referencing
    &macrovar
    before it exists,
    %if
    evaluating data-step variables (use
    if
    /
    symget
    instead)
  • Automatic macro variables (
    &syscc
    ,
    &syswarningtext
    ,
    &syserrortext
    ,
    &sysdate
    ,
    &sysuserid
    , etc.) are READ-ONLY — attempting to overwrite them (e.g.
    %let syswarningtext=;
    or
    call symput('syscc',...)
    ) raises
    ERROR: Unable to assign value to a macro variable that is read only
    (or similar). Never try to "clear" them.
  • Truncation from implicit length=8 on first assignment
  • proc sql
    cartesian product warnings
  • 非预期的多对多MERGE操作
  • 自动变量
    _ERROR_
    /隐式RETAIN带来的意外问题
  • 宏时机问题:在
    &macrovar
    存在前引用它、
    %if
    评估DATA step变量(应使用
    if
    /
    symget
    替代)
  • 自动宏变量(
    &syscc
    &syswarningtext
    &syserrortext
    &sysdate
    &sysuserid
    等)为只读——尝试覆盖它们(例如
    %let syswarningtext=;
    call symput('syscc',...)
    )会触发
    ERROR: Unable to assign value to a macro variable that is read only
    (或类似错误)。切勿尝试“清除”这些变量。
  • 首次赋值时因隐式长度为8导致的截断问题
  • proc sql
    笛卡尔积警告