如何在 SAS 中找到最后一组的第一行,其中顺序很重要?
How do I find first row of last group in SAS, where ordering matters?
我想在这方面寻求帮助,因为我是 SAS 的新手,但是 PROC SQL 方法也可用。
我的数据集有 ID、时间变量和标志。在我按 id 和时间排序后,我需要找到最后一个标记 group/streak 的第一个标记观察。如:
ID TIME FLAG
1 2 1
1 3 1
1 4 1
1 5 0
1 6 1
1 7 0
1 8 1
1 9 1
1 10 1
2 2 0
2 3 1
2 4 1
2 5 1
2 6 1
2 7 1
在这里,我希望我的脚本 return ID 1 时间为 8 的行,因为它是最后一个“连胜”或标记组的第一个观察结果。对于 ID 2,它应该是时间为 3 的地方。
期望的输出:
ID TIME FLAG
1 8 1
2 3 1
我正在尝试首先使用 using。最后。在这里,但我想这里的问题是我将时间流离失所的标记 groups/streaks 视为不同的组,而 SAS 将它们视为仅由标记分隔,因此简单的“先取后取”。不够。
我也在考虑将标志折叠成一个字符串并使用正则表达式前瞻,但我无法想出方法或模式。
我只想编写一个双 DOW 循环。第一个将让您计算要输出的此 ID 的观察值,第二个将再次读取记录并输出所选观察值。
您可以在 BY 语句中使用 NOTSORTED 关键字让 SAS 计算 FIRST.FLAG 变量。
data have;
input ID TIME FLAG;
cards;
1 2 1
1 3 1
1 4 1
1 5 0
1 6 1
1 7 0
1 8 1
1 9 1
1 10 1
2 2 0
2 3 1
2 4 1
2 5 1
2 6 1
2 7 1
;
data want;
do obs=1 by 1 until(last.id);
set have;
by id flag notsorted;
if first.flag then want=obs;
end;
do obs=1 to obs;
set have;
if obs=want then output;
end;
drop obs want;
run;
通过 id 遍历数据集。使用 lag 函数查看 flag 的当前值和先前值。如果当前值为 1 而前一个值为 0,或者这是该 ID 的第一个观察值,则将时间值写入保留变量。只输出每个 id 的最后一次观察。保留的变量应该包含最后一个标记组的第一次标记观察的时间:
data result;
set have;
by id;
retain firstflagged;
prevflag = lag(flag);
if first.id and flag = 1 then firstflagged = time;
else if first.id and flag = 0 then firstflagged = .;
else if flag = 1 and prevflag = 0 then firstflagged = time;
if last.id then output;
keep id firstflagged flag;
rename firstflagged = time;
run;
我想在这方面寻求帮助,因为我是 SAS 的新手,但是 PROC SQL 方法也可用。
我的数据集有 ID、时间变量和标志。在我按 id 和时间排序后,我需要找到最后一个标记 group/streak 的第一个标记观察。如:
ID TIME FLAG
1 2 1
1 3 1
1 4 1
1 5 0
1 6 1
1 7 0
1 8 1
1 9 1
1 10 1
2 2 0
2 3 1
2 4 1
2 5 1
2 6 1
2 7 1
在这里,我希望我的脚本 return ID 1 时间为 8 的行,因为它是最后一个“连胜”或标记组的第一个观察结果。对于 ID 2,它应该是时间为 3 的地方。
期望的输出:
ID TIME FLAG
1 8 1
2 3 1
我正在尝试首先使用 using。最后。在这里,但我想这里的问题是我将时间流离失所的标记 groups/streaks 视为不同的组,而 SAS 将它们视为仅由标记分隔,因此简单的“先取后取”。不够。
我也在考虑将标志折叠成一个字符串并使用正则表达式前瞻,但我无法想出方法或模式。
我只想编写一个双 DOW 循环。第一个将让您计算要输出的此 ID 的观察值,第二个将再次读取记录并输出所选观察值。
您可以在 BY 语句中使用 NOTSORTED 关键字让 SAS 计算 FIRST.FLAG 变量。
data have;
input ID TIME FLAG;
cards;
1 2 1
1 3 1
1 4 1
1 5 0
1 6 1
1 7 0
1 8 1
1 9 1
1 10 1
2 2 0
2 3 1
2 4 1
2 5 1
2 6 1
2 7 1
;
data want;
do obs=1 by 1 until(last.id);
set have;
by id flag notsorted;
if first.flag then want=obs;
end;
do obs=1 to obs;
set have;
if obs=want then output;
end;
drop obs want;
run;
通过 id 遍历数据集。使用 lag 函数查看 flag 的当前值和先前值。如果当前值为 1 而前一个值为 0,或者这是该 ID 的第一个观察值,则将时间值写入保留变量。只输出每个 id 的最后一次观察。保留的变量应该包含最后一个标记组的第一次标记观察的时间:
data result;
set have;
by id;
retain firstflagged;
prevflag = lag(flag);
if first.id and flag = 1 then firstflagged = time;
else if first.id and flag = 0 then firstflagged = .;
else if flag = 1 and prevflag = 0 then firstflagged = time;
if last.id then output;
keep id firstflagged flag;
rename firstflagged = time;
run;