SAS如何使用ARRAY

时间:2017-02-13 06:49:30

标签: arrays variables sas

我是SAS新手,遇到了切换列内容的问题。

我有一个像:

这样的数据集
data switch;
input total A1 A2 A3 A4 A5 A6 A7 A8 A9 A10;
cards;
1234567890 1 2 3 4 5 6 7 8 9 0
1234567890 1 2 3 4 5 6 7 8 9 0
1234567890 1 2 3 4 5 6 7 8 9 0
1234567890 1 2 3 4 5 6 7 8 9 0
1234567890 1 2 3 4 5 6 7 8 9 0
1234567890 1 2 3 4 5 6 7 8 9 0
1234567890 1 2 3 4 5 6 7 8 9 0
1234567890 1 2 3 4 5 6 7 8 9 0
1234567890 1 2 3 4 5 6 7 8 9 0
;
run;

所以目标是获得A10中的值并填入A1,A9到A2,A8到A3等等。 LIKE:

total      A1 A2 A3 ...
1234567890 0  9  8
1234567890 0  9  8
1234567890 0  9  8

所以通常要向后切换列(第一个变量除外)。

需要数组。

我根本不知道该怎么做,因为SAS读取行(观察)。

有人可以引导我解决这个问题吗?

非常感谢!

============================= 感谢大家的想法,我也想出了一种方法,也就是借用临时或中间数组:

data want;
set switch;
array old(1:10) A1 - A10;
array mid(1:10) B1 - B10;

do i=1 to 10;
mid[i]=old[i];
end;

array new(1:10) A1 - A10;
do i=1 to 10;
new[i]=mid[11-i];   /* input in new array with mid array in reverse order */
end;

drop B1 - B10 i;  /* drop unwanted column */
run;

4 个答案:

答案 0 :(得分:2)

这是一种使用两个数组和两个do循环的方法。基本上以相反的顺序将值存储在新变量中,然后将它们移回原始变量。使用rename语句可以在没有数组的情况下完成类似的方法。

data want;
  set switch;

  array var (*) A1-A10;
  array holder (10) H1-H10;

  do i = 1 to (10);
    holder{i} = var{(10 - i + 1)};
  end;

  do i = 1 to 10;
    var{i} = holder{i};
  end;

  drop H1-H10 i;  
run;

修改 将方法简化为一个临时变量,一个数组和一个循环:

data want;
  set switch;
  array var (*) a1-a10;


  do i = 1 to (floor(dim(var)/2));

    a11 = var{i};
    var{i}  = var{(dim(var)- i +1)};
    var{(dim(var) - i +1)} = a11;

  end;

  drop i a11;
run;

答案 1 :(得分:0)

将所有内容乘以-1,使用call sortn,然后再次乘以-1。

除非你有更多不同的数据......?

否则,再次进行转置,排序和转置。

答案 2 :(得分:0)

这是一个反转顺序或价值而不依赖于排序的解决方案。创建了3个数组,一个用于原始变量顺序,一个用于反向变量,一个临时数组填充与反向数组相同的值。这个额外的数组是必需的,因为它中的值在do循环期间不会更新,如果您刚刚使用前2个数组,这将是一个问题。

data switch;
input total A1 A2 A3 A4 A5 A6 A7 A8 A9 A10;
cards;
1234567890 1 2 3 4 5 6 7 8 9 0
1234567890 1 2 3 4 5 6 7 8 9 0
1234567890 1 2 3 4 5 6 7 8 9 0
1234567890 1 2 3 4 5 6 7 8 9 0
1234567890 1 2 3 4 5 6 7 8 9 0
1234567890 1 2 3 4 5 6 7 8 9 0
1234567890 1 2 3 4 5 6 7 8 9 0
1234567890 1 2 3 4 5 6 7 8 9 0
1234567890 1 2 3 4 5 6 7 8 9 0
;
run;

data want;
set switch;
array vars(*) A1-A10; /* array in original order */
array rev_vars(*) A10-A1; /* array in reverse order */
array _temp(10) _temporary_;
/* populate temporary array with values in reverse order */
do i=1 to dim(rev_vars);
    _temp{i} = rev_vars{i};
end;
/* rewrite existing values in reverse order */
do i=1 to dim(vars);
    vars{i}=_temp{i};
end;
drop i;
run;

答案 3 :(得分:0)

这是另一个只需要三个临时变量而不是临时数组的解决方案 - 它在数组中交换值,从末端到中间。如果数组具有奇数个元素,则中间元素保持不变,它仍然可以正常工作。

data switch;
input total A1 A2 A3 A4 A5 A6 A7 A8 A9 A10;
cards;
1234567890 1 2 3 4 5 6 7 8 9 0
1234567890 1 2 3 4 5 6 7 8 9 0
1234567890 1 2 3 4 5 6 7 8 9 0
1234567890 1 2 3 4 5 6 7 8 9 0
1234567890 1 2 3 4 5 6 7 8 9 0
1234567890 1 2 3 4 5 6 7 8 9 0
1234567890 1 2 3 4 5 6 7 8 9 0
1234567890 1 2 3 4 5 6 7 8 9 0
1234567890 1 2 3 4 5 6 7 8 9 0
;
run;

data out;
  set switch;
  array a[*] a1-a10;
  _a = 1;
  _b = dim(a);
  do while (_a < _b);
    * Swap elements _A and _B;
    _temp = a[_a];
    a[_a] = a[_b];
    a[_b] = _temp;
    * _A moves forward from the beginning of the array;
    _a = _a + 1;
    * _B moves backward from the end;
    _b = _b - 1;
  end;
run;