【问题标题】:How to disable internal ordering in SAS?如何在 SAS 中禁用内部排序?
【发布时间】:2017-04-28 09:59:58
【问题描述】:

假设我有一个带有两列的管道分隔文本文件:

LIBRARY_NAME|TABLE_NAME
A.|ZZZ
A.|XXX
B.|QQQ
B.|AAA
B.|MNO
B.|OPQ

我使用 INFILE 语句导入文件并将两列的所有值分别分配给宏变量 &LIB 和 &TAB。

/* COUNT THE TABLES IN ORDER TO BE ABLE TO LOOP THROUGH THEM LATER: */
PROC SQL;

    SELECT COUNT(*) INTO :TABLE_C FROM TABLE_NAMES; 
    /* DELETE LEADING BLANKS FROM THE COUNT: */
    %LET TABLE_COUNT = &TABLE_C; 

QUIT;


/* MAKE A LIST OF THE LIBRARY & TABLE NAMES: */
PROC SQL NOPRINT;

    SELECT 
        LIBRARY_NAME

        INTO 
            :LIB1 - :LIB&TABLE_COUNT

        FROM 
            WORK.TABLE_NAMES;

    SELECT 
        DISTINCT TABLE_NAME

        INTO 
            :TAB1 - :TAB&TABLE_COUNT

        FROM 
            WORK.TABLE_NAMES;

QUIT;

所以本质上,我现在有两个包含所有库和表的“数组”。 现在我想在一个宏中执行此 DO LOOP,该宏会转到相关库和表,检索相关数据并在 WORK 库中创建相关表:

%DO N = 1 %TO &COUNT;

    PROC SQL;

        CREATE TABLE WORK.&&TAB&N AS 

            SELECT
                *

                FROM
                    &&LIB&N.&&TAB&N

                WHERE
                    AGE > 50;

    QUIT;

%END;

问题是,它只创建了一些表。我收到这个错误,说表 A.AAA 和 A.MNO 不存在。这是真的。所以不知何故,SAS 混合了这两列或它们的顺序。它不是按照它们在源文件中出现的顺序进行循环并将正确的库与正确的表结合起来,而是以某种方式将其混合在一起。 编辑:我现在很确定 SAS 在 DO LOOP 之前自动对库和表名称的“数组”进行排序,这对我来说显然不是很好,因为它混合了所有内容。 如何强制 SAS 不自动对值进行排序,以便保留两列的原始顺序? EDIT2: 当我更改源文本文件中库的顺序时(即将 B 表放在 A 表前面),它就可以工作了。真奇怪。

任何帮助表示赞赏。

【问题讨论】:

  • 你需要发布你用来读取管道和创建数组的代码..
  • 我可以向您保证,sas 不会对那些宏“数组”进行排序,因为它们实际上不是数组 - 只是一组编号的单个宏变量。
  • 您正在使用输入列表中的成员名称创建工作数据集名称。但是您的输入列表包含来自多个源 libref 的数据集。有没有可能你只是用 B.XXX 的数据覆盖了 A.XXX 的数据形式?
  • 添加了创建这两组编号的单个宏变量的代码

标签: loops variables macros sas


【解决方案1】:

您可以跳过 PROC SQL 代码。只需在读取源文件时生成宏变量即可。

data table_names ;
  infile 'myfile' dsd dlm='|' firstobs=2 truncover ;
  length library_name $9 table_name $32 ;
  input library_name table_name ;
  call symputx(cats('LIB',_n_),library_name);
  call symputx(cats('TAB',_n_),table_name);
run;

【讨论】:

    【解决方案2】:

    DISTINCT 是对您的数据进行排序的原因。如果没有某种类型,SQL 无法确定什么是唯一的。 您也不需要提前知道项目的数量,SAS 默认会创建足够多的宏变量。 您可以通过创建单个宏变量列表来避免这种情况。

     Proc SQL noprint;
         Select distinct catx('.', library_name, table_name) into :ref_list1-
     From work.table_names;
     Quit;
    
    %put &ref_list1;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-08
      • 1970-01-01
      • 2019-07-30
      • 2012-01-27
      • 2011-05-03
      • 2014-06-01
      相关资源
      最近更新 更多