我是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;
答案 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)
答案 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;