在SAS中,我有一个数据集,如下所示:
columnA columnB columnC
1 2 .
3 . .
我想根据以下forst 3列中的值创建新变量column1,column2和column3,其中1 =是,2 =否。
columnA columnB columnC column1 column2 column3
1 2 . 1 1 2
3 . . 2 2 1
是否有比以下方式更短的书写方式:
If columnA = 1 or columnB = 1 or columnC = 1 then column1=1; else column1=2;
答案 0 :(得分:1)
这是阵列成为您最好的朋友的时候。我不认识你,但我讨厌重复的工作。我竭尽全力去寻找一种非重复的做事方式。从外观上看,今天就是您的一天!让我们熟悉数组。
一种实现方式
data want;
set have;
array alpha_column[*] columnA--columnC;
array bin_column[3] _TEMPORARY_;
/* Convert to your columns to binary to make this easier to work with:
1 = yes
0 = no
*/
do i = 1 to dim(bin_column);
bin_column[i] = (alpha_column[i] = 1);
end;
/* If any of the columns are yes, then column1 = 1 */
column1 = (sum(of bin_column[*]) > 0);
drop i;
run;
说明
array alpha_column[*] columnA--columnC;
这告诉SAS根据columnA,columnB和columnC创建变量数组。 --
是一种快捷方式,它告诉SAS包括columnA
和columnC
之间的所有变量。 [*]
告诉SAS自动计算阵列的大小。
您现在可以使用单个变量引用每列。 alpha_column[1]
指向columnA。 alpha_column[2]
指向columnB等。
array bin_column[3] _TEMPORARY_;
这告诉SAS创建带有3个变量的临时内存阵列。指定_TEMPORARY_
时,它们不会写入输出数据集。我们希望这将是/否值转换为简单的二进制值。
do i = 1 to dim(bin_column);
bin_column[i] = (alpha_column[i] = 1);
end;
遍历数组bin_column
中的所有列。 dim(bin_column)
告诉SAS拉出阵列的大小以防止超出范围的阵列错误。该语句检查alpha_column
的每个值是否为1。如果为bin_column
为1,否则为bin_column
为0。
语句variable = (boolean test statement)
是SAS中一个有用的快捷方式,可在一个步骤中创建二进制变量。
column1 = (sum(of bin_column[*]) > 0)
这使用of
运算符对整个数组进行求和。 sum(of array[*]
,sum(of var1-var3)
和sum(of var:)
都是避免重复输入的快捷方式:sum(var1, var2, var3, var4, ...)
。
在这里,我们要说的是如果任何二进制列为1,则这些列的总和必须大于0。如果是,则有人说是。如果不是,则有人拒绝。
答案 1 :(得分:0)
您可以使用WHICHN()
(如果您的值实际上是字符串,请改为使用whichc()
)。如果找不到该值,它将返回零。因此,只需测试该值是否不为零即可。若要将COLUMN1设置为0或1,则不需要IF / THEN,只需将布尔表达式的结果分配给变量即可。
column1 = 0 < whichn(1,of columnA columnB columnC);
您可以进行较小的调整以测试2或3的值。或者,如果您真的想将NO编码为2而不是零。
答案 2 :(得分:0)
要基于@Tom WHICHN
。从2减去逻辑0(false)/ 1(true)以计算编码1(true)/ 2(false)
column1 = 2 - (whichn(1,of columnA columnB columnC) ne 0);
column2 = 2 - (whichn(2,of columnA columnB columnC) ne 0);
column3 = 2 - (whichn(3,of columnA columnB columnC) ne 0);