检查数字,时间等的正确排序

时间:2014-01-09 15:18:09

标签: sas

我的数据看起来像这样:

data tmp ;
  input id var1 - var5 ;
  datalines ;
  1 1 2 3 4 5
  2 1 2 . . .
  3 1 . . . 4
  4 . 3 . . . 
  5 . . . . 5
  6 1 3 2 2 3
  7 5 3 7 8 9
  8 1 . . . 2
  9 1 . 2 3 4
  ;
run ;

我正在尝试确定n个变量是否正确'有序'。通过命令,我的意思是数字或顺序(或甚至字母)。所以在这个例子中,我想要的输出是:

dummy = 1 1 1 1 1 0 0 1 1因为dummy = 1的顺序正确。

如果我有完整的数据,那将是微不足道的:

if var1 <= var2 <= ... <= varn then dummy = 1; else dummy = 0;

遗憾的是,我没有完整的数据。所以问题可能是sas将.视为一个非常小的数字(?),而且我也无法对.执行操作,因为这也失败了:

if 0 * (var1 = .) + var1 <= 
   var1 * (var2 = .) + var2 <= 
   var2 * (var3 = .) + var3 <= ... <= 
   var_n-1 * (varn = .) + varn 
then dummy = 1; 
 else dummy = 0;

基本上这将检查变量是否为.,如果是,则使用不等式中的先前值,但如果没有丢失,则继续正常进行。这有时会起作用,但仍然需要大部分信息都是不可错过的。

我也尝试了类似的事情:

if var2 = max(var1, var2) & var1 <= var2 & 
   var3 = max(var1 -- var3) & var2 <= var3 & ...

但这种方法也需要完整的数据。我已经尝试将数据转换为长格式,这样我就可以删除缺少的列(并且只保留我感兴趣知道顺序的变量)但是数千个变量的转置数据集对我没用(如果你要转换回宽,那么仍然会缺少列。)

显然,我不是最好的SASer,但我想写一个宏或其他东西,因为这个问题对我来说很多(基本上只是一个数据检查,以查看日期是否有序,并发生在他们应该关于他们的相对时间表。)

以下是所有代码:

data tmp ;
    input id var1 - var5 ;
    datalines ;
    1 1 2 3 4 5 
    2 1 2 . . .
    3 1 . . . 4
    4 . 3 . . .
    5 . . . . 5
    6 1 3 2 2 3
    7 5 3 7 8 9
    8 1 . . . 2
    9 1 . 2 3 4
    ;
run ;

data tmp1 ; 
    set tmp ;
    if var1 <= var2 <= var3 <= var4 <= var5 then dummy1 = 1 ; else dummy1 = 0 ;

    if 0 * (var1 = .) + var1 <=
      var1 * (var2 = .) + var2 <= 
      var2 * (var3 = .) + var3 <=
      var3 * (var4 = .) + var4 <=
      var4 * (var5 = .) + var5
    then dummy2 = 1 ;
     else dummy2 = 0 ;

    if var2 = max(var1,var2) & var1 ~= var2 &
       var3 = max(var1, var2, var3) & var2 ~= var3 &
       var4 = max(var1, var2, var3, var4) & var3 ~= var4 &
       var5 = max(var1, var2, var3, var4, var5) & var4 ~= var5
    then dummy3 = 1 ; 
     else dummy3 = 0 ;

    * none of dummy1 - 3 pick up the observations that are in proper order ;
run ;


data tmp1_varsIwant ;
    set tmp1 ;
    keep id var1 -- var5 ;
run ;
proc transpose data = tmp1_varsIwant out = tmp1_long ;
    by id ;
run ;
data tmp1_long ;
    set tmp1_long ;
    if col1 = . then delete ;
    if _name_ in('var6', 'var999') then delete ;
run ;
proc sort data = tmp1_long ;
    by id col1 ;
run ;

1 个答案:

答案 0 :(得分:3)

也许您可以将所有逻辑强制转换为一个条件,但使用这样的循环可能更简单:

data tmp1 ; 
    set tmp ;
    array vars (*) var1-var5;
    last_highest = .;
    dummy = 1;
    do i = 1 to 5;
        if vars(i) > . and vars(i) < last_highest then do;
            dummy = 0;
            leave;
        end;
        last_highest = coalesce(vars(i),last_highest);
    end;
run ;