SAS: Как отфильтровать, используя несколько ключевых слов из группы - PullRequest
0 голосов
/ 04 мая 2019

У меня есть данные, которые содержат действия, которые каждый человек выполняет в течение сезона -

Name Season Activity
A   1   x
A   1   y
A   1   z
A   1   t
A   2   y
A   2   u
A   3   x
B   1   u
B   1   v
B   2   r
B   2   x
B   2   y
B   3   k
B   3   j

Если у человека есть активность x & y в сезоне 1, тогда я хочу, чтобы все его строки в первом сезоне имелифлаг да-

Name    Season  Disease Flag
A   1   x   Yes
A   1   y   Yes
A   1   z   Yes
A   1   t   Yes
A   2   y   No
A   2   u   No
A   3   x   No

аналогично у меня разные сочетания болезней для разных времен года и активности.У меня есть 5 переменных деятельности (активность 1 - деятельность 5) и 30 комбинаций активности, для которых мне нужно создать 5 флагов.Я не могу написать эффективный код для этого.

Код, который я придумал, -

CREATE TABLE activity_x AS                  
SELECT a.*
FROM table1 as a join (SELECT distinct person, season from table1 
where activity= 'x') as b
on a.person  = b.person and a.season= b.season
ORDER BY person, season;
QUIT;

Это даст мне набор данных со всей информацией для человека исезоны, в которых по крайней мере одно действие в сезоне равно x.

Аналогичным образом я бы повторил для действия y и получил бы набор данных.

Затем найдите внутреннее соединение двух.Но проблема в том, что комбинации кодов действий очень сложны

Any one of this list    and     Any one of this list
a                                    r
b+c                                  m
d+c                                  n
s+c                                  o

Есть ли лучший способ сделать это?

1 Ответ

0 голосов
/ 07 мая 2019

Вот двойной подход DOW-loop для первой части вашего вопроса:

data have;
input Name $ Season Activity $;
cards;
A   1   x
A   1   y
A   1   z
A   1   t
A   2   y
A   2   u
A   3   x
B   1   u
B   1   v
B   2   r
B   2   x
B   2   y
B   3   k
B   3   j
;
run;

data want;
 do _n_ = 1 by 1 until (last.Season);
  set have;
  by Name Season;
  if Activity = 'x' then __x_flag = 1;
  if Activity = 'y' then __y_flag = 1;
 end;
 do _n_ = 1 to _n_;
  set have;
  xy_flag = __x_flag and __y_flag;
  output;
 end;
 drop __:;
run;

Вы можете легко обобщить это, чтобы справиться с любыми условиями - просто создайте один флаг на Activity значениев первом цикле, а затем объединить их во втором цикле.

Это должно работать намного лучше, чем ваш подход SQL, так как он делает только один проход через данные, а не 1 запрос на значение.

...