SAS 从单变量新建变量数组
SAS New Variable Array from Single Variable
应该是一个简单的问题,我无法回答。我得到了一些调查数据,其中有几个问题允许“select 尽可能多的适用。”对于这些问题,响应选项存储为单个变量,以逗号分隔。
例如,假设问题 1 (Q1) 有 9 个不同的回答选项。对于该问题,第 1 个人可能将三个答案存储为:1、3、10,而第 2 个人可能将四个答案存储为:2、3、8、9。
从这个单一变量 (Q1),我想创建 9 个单独的变量,每个变量对应一个响应选项(Q1_1 到 Q1_9)。我相信我可以使用一个 ARRAY 和一个 DO 循环在一个数据步骤中完成此操作,但是 INDEX 或 IN 函数都不起作用。下面是我一直在使用的代码。
DATA Final; SET Final;
ARRAY Q1b{9} Q1_1 - Q1_9; *new variables I want to create;
DO i = 1 TO 9;
IF NOT MISSING(Q1) THEN Q1b{i} = 0; *works;
IF INDEX(Q1,"i") THEN Q1b{i} = 1; *Doesn't work;
IF Q1 IN: ("i") THEN Q1b{i} = 1; *Doesn't work either;
END;
RUN;
使用上面示例中的人的回答,Q1_1 对第 1 个人的值为 1,而对第 2 个人的值为 0。同样,第 1 个人 Q1_2 的值为将是 0,而对于第 2 个人,它将是 1。我猜它与 SAS 存储循环 i 的方式有关(我认为它类似于没有 & 的宏变量)。思想受到赞赏。
谢谢,
瑞安
- 通常不应使用相同的输入和输出数据集名称。很难调试,有时你会得到意想不到的输出。
- 循环前检查变量是否为空,避免不必要的循环
- 从 i 中删除引号以使用数字 i。在引号中它正在寻找字母 i,而不是迭代器变量 i.
可能是这样的:
DATA Final_expanded; /*1*/
SET Final;
ARRAY Q1b{9} Q1_1 - Q1_9; *new variables I want to create;
if not missing(q1) then DO i = 1 TO 9; /*2*/
IF INDEX(Q1, i) THEN Q1b{i} = 1; /*3*/
END;
RUN;
编辑:由于某种原因无法让它工作,但这个方法确实有效。
DATA Final_expanded; /*1*/
SET have;
ARRAY Q1b{9} Q1_1 - Q1_9; *new variables I want to create;
nwords = countw(q1);
if not missing(q1) then DO i = 1 TO nwords; /*2*/
index = scan(q1, i);
q1b(index) = 1;
END;
RUN;
INDEX() 需要字符串。
IF INDEX(Q1,cats(i)) THEN Q1b{i} = 1;
请注意,如果可能的回答超过 9 个,则不会缩放,因为数字“1”将同时出现在“1”和“10”中。所以你可能想改用 INDEXW() 。确保除了逗号之外还包含 space 作为分隔符,以防止逗号周围的尾随 space 或 space 成为字符串中单词的一部分。
IF INDEXW(Q1,cats(i),' ,') THEN Q1b{i} = 1;
布尔表达式的计算结果为 0 或 1。因此您的程序可能只是:
data WANT;
set HAVE;
array q1_ [9] ;
do i = 1 to dim(q1_);
q1_[i] = 0<indexw(q1,cats(i),' ,');
end;
run;
应该是一个简单的问题,我无法回答。我得到了一些调查数据,其中有几个问题允许“select 尽可能多的适用。”对于这些问题,响应选项存储为单个变量,以逗号分隔。
例如,假设问题 1 (Q1) 有 9 个不同的回答选项。对于该问题,第 1 个人可能将三个答案存储为:1、3、10,而第 2 个人可能将四个答案存储为:2、3、8、9。
从这个单一变量 (Q1),我想创建 9 个单独的变量,每个变量对应一个响应选项(Q1_1 到 Q1_9)。我相信我可以使用一个 ARRAY 和一个 DO 循环在一个数据步骤中完成此操作,但是 INDEX 或 IN 函数都不起作用。下面是我一直在使用的代码。
DATA Final; SET Final;
ARRAY Q1b{9} Q1_1 - Q1_9; *new variables I want to create;
DO i = 1 TO 9;
IF NOT MISSING(Q1) THEN Q1b{i} = 0; *works;
IF INDEX(Q1,"i") THEN Q1b{i} = 1; *Doesn't work;
IF Q1 IN: ("i") THEN Q1b{i} = 1; *Doesn't work either;
END;
RUN;
使用上面示例中的人的回答,Q1_1 对第 1 个人的值为 1,而对第 2 个人的值为 0。同样,第 1 个人 Q1_2 的值为将是 0,而对于第 2 个人,它将是 1。我猜它与 SAS 存储循环 i 的方式有关(我认为它类似于没有 & 的宏变量)。思想受到赞赏。
谢谢, 瑞安
- 通常不应使用相同的输入和输出数据集名称。很难调试,有时你会得到意想不到的输出。
- 循环前检查变量是否为空,避免不必要的循环
- 从 i 中删除引号以使用数字 i。在引号中它正在寻找字母 i,而不是迭代器变量 i.
可能是这样的:
DATA Final_expanded; /*1*/
SET Final;
ARRAY Q1b{9} Q1_1 - Q1_9; *new variables I want to create;
if not missing(q1) then DO i = 1 TO 9; /*2*/
IF INDEX(Q1, i) THEN Q1b{i} = 1; /*3*/
END;
RUN;
编辑:由于某种原因无法让它工作,但这个方法确实有效。
DATA Final_expanded; /*1*/
SET have;
ARRAY Q1b{9} Q1_1 - Q1_9; *new variables I want to create;
nwords = countw(q1);
if not missing(q1) then DO i = 1 TO nwords; /*2*/
index = scan(q1, i);
q1b(index) = 1;
END;
RUN;
INDEX() 需要字符串。
IF INDEX(Q1,cats(i)) THEN Q1b{i} = 1;
请注意,如果可能的回答超过 9 个,则不会缩放,因为数字“1”将同时出现在“1”和“10”中。所以你可能想改用 INDEXW() 。确保除了逗号之外还包含 space 作为分隔符,以防止逗号周围的尾随 space 或 space 成为字符串中单词的一部分。
IF INDEXW(Q1,cats(i),' ,') THEN Q1b{i} = 1;
布尔表达式的计算结果为 0 或 1。因此您的程序可能只是:
data WANT;
set HAVE;
array q1_ [9] ;
do i = 1 to dim(q1_);
q1_[i] = 0<indexw(q1,cats(i),' ,');
end;
run;