如何使用 SAS 从特定 ROW 中获取第一个和最后一个 MISSING 值
How can I get the first and the last MISSING value from a particular ROW using SAS
有以下问题,我想找出一行中第一个和最后一个缺失值。以下面的代码为例:
data example;
input id var1 var2 var3 var4 var5 var6 var7 var8 var9 var10 var11 var12;
cards;
A 1 2 3 . . . . . 1 1 1 3
B 3 3 2 1 3 2 1 . . . . .
C . . . . 1 2 3 1 2 3 2 .
D 3 . 1 . 3 . 1 . 3 . 1 .
F 1 3 . . 1 3 . . 1 3 . .
E 3 2 1 . . . . . 1 1 1 3
G 3 3 2 1 3 2 1 . . . . .
H . . . . . 1 2 3 1 2 3 2
I 3 . 1 . 3 . 1 . 3 . 1 .
J A E . . A E . . A E . .
;
在 A 行中,第一个是 var4,最后一个是 var8
在 D 行中,第一个是 var2,最后一个是 var12
谢谢。
使用 ARRAY 和几个 DO 循环似乎很简单。
让我们清理您的数据步骤并添加一个没有缺失值的示例。
missing abcdefghijklmnopqrstuvwxyz;
data example;
input id $ var1-var12;
cards;
A 1 2 3 . . . . . 1 1 1 3
B 3 3 2 1 3 2 1 . . . . .
C . . . . 1 2 3 1 2 3 2 .
D 3 . 1 . 3 . 1 . 3 . 1 .
F 1 3 . . 1 3 . . 1 3 . .
E 3 2 1 . . . . . 1 1 1 3
G 3 3 2 1 3 2 1 . . . . .
H . . . . . 1 2 3 1 2 3 2
I 3 . 1 . 3 . 1 . 3 . 1 .
J A E . . A E . . A E . .
K 1 2 3 4 5 6 7 8 9 10 11 12
;
然后在数据步骤中创建一个包含要检查的变量的数组(按照您希望检查的顺序)。然后使用两个 do 循环。计数时确保在找到 none 时捕获大小写。默认情况下,结果将为 N+1,因此您可能希望它为零,而不是像倒数时得到的结果那样。
data want;
set example;
array vars var1-var12;
do first=1 to 12 while(not missing(vars[first])); end;
if first>12 then first=0;
do last=12 to 1 by -1 while(not missing(vars[last])); end;
run;
结果;
将您的所有值连接成一个字符串。找到第一个 .
和最后一个 .
在字符串中的位置。
data want;
set example;
sequence_char = cats(of var1-var12);
missing_start = find(sequence_char, '.');
missing_end = length(sequence_char) - find(strip(reverse(sequence_char)), '.') + 1;
run;
输出:
id sequence_char missing_start missing_end
A 123.....1113 4 8
B 3321321..... 8 12
C ....1231232. 1 12
D 3.1.3.1.3.1. 2 12
F 13..13..13.. 3 12
E 321.....1113 4 8
G 3321321..... 8 12
H .....1231232 1 5
I 3.1.3.1.3.1. 2 12
J ............ 1 12
我在这里假设这些字母不应该算作丢失。如果是,则替换“如果 v(i) = ”。与“如果缺少(v(i))”。
data want (drop=i);
set have;
array v(12) var1-var12;
do i = 1 to 12;
if v(i) = . then do;
first_missing = min(first_missing,i);
last_missing = max(last_missing,i);
end;
end;
run;
有以下问题,我想找出一行中第一个和最后一个缺失值。以下面的代码为例:
data example;
input id var1 var2 var3 var4 var5 var6 var7 var8 var9 var10 var11 var12;
cards;
A 1 2 3 . . . . . 1 1 1 3
B 3 3 2 1 3 2 1 . . . . .
C . . . . 1 2 3 1 2 3 2 .
D 3 . 1 . 3 . 1 . 3 . 1 .
F 1 3 . . 1 3 . . 1 3 . .
E 3 2 1 . . . . . 1 1 1 3
G 3 3 2 1 3 2 1 . . . . .
H . . . . . 1 2 3 1 2 3 2
I 3 . 1 . 3 . 1 . 3 . 1 .
J A E . . A E . . A E . .
;
在 A 行中,第一个是 var4,最后一个是 var8
在 D 行中,第一个是 var2,最后一个是 var12
谢谢。
使用 ARRAY 和几个 DO 循环似乎很简单。
让我们清理您的数据步骤并添加一个没有缺失值的示例。
missing abcdefghijklmnopqrstuvwxyz;
data example;
input id $ var1-var12;
cards;
A 1 2 3 . . . . . 1 1 1 3
B 3 3 2 1 3 2 1 . . . . .
C . . . . 1 2 3 1 2 3 2 .
D 3 . 1 . 3 . 1 . 3 . 1 .
F 1 3 . . 1 3 . . 1 3 . .
E 3 2 1 . . . . . 1 1 1 3
G 3 3 2 1 3 2 1 . . . . .
H . . . . . 1 2 3 1 2 3 2
I 3 . 1 . 3 . 1 . 3 . 1 .
J A E . . A E . . A E . .
K 1 2 3 4 5 6 7 8 9 10 11 12
;
然后在数据步骤中创建一个包含要检查的变量的数组(按照您希望检查的顺序)。然后使用两个 do 循环。计数时确保在找到 none 时捕获大小写。默认情况下,结果将为 N+1,因此您可能希望它为零,而不是像倒数时得到的结果那样。
data want;
set example;
array vars var1-var12;
do first=1 to 12 while(not missing(vars[first])); end;
if first>12 then first=0;
do last=12 to 1 by -1 while(not missing(vars[last])); end;
run;
结果;
将您的所有值连接成一个字符串。找到第一个 .
和最后一个 .
在字符串中的位置。
data want;
set example;
sequence_char = cats(of var1-var12);
missing_start = find(sequence_char, '.');
missing_end = length(sequence_char) - find(strip(reverse(sequence_char)), '.') + 1;
run;
输出:
id sequence_char missing_start missing_end
A 123.....1113 4 8
B 3321321..... 8 12
C ....1231232. 1 12
D 3.1.3.1.3.1. 2 12
F 13..13..13.. 3 12
E 321.....1113 4 8
G 3321321..... 8 12
H .....1231232 1 5
I 3.1.3.1.3.1. 2 12
J ............ 1 12
我在这里假设这些字母不应该算作丢失。如果是,则替换“如果 v(i) = ”。与“如果缺少(v(i))”。
data want (drop=i);
set have;
array v(12) var1-var12;
do i = 1 to 12;
if v(i) = . then do;
first_missing = min(first_missing,i);
last_missing = max(last_missing,i);
end;
end;
run;