Не уверен, почему вы обрабатываете 4 действия для флагов, когда их только 3.
Некоторые идеи:
- Перевод имен столбцов в нумерованные суффиксы уменьшит некоторые из обои эффект.
activities_p1-activities_p3
- Преобразование имен столбцов флагов в суффиксы чисел
flag_p1_1-flag_p1_4
flag_p2_1-flag_p2_4
flag_p3_1-flag_p3_4
- Используйте
DIM
, чтобы не выходить за границы массива. - Используйте двумерный массив для флагов
- Используйте прямую адресацию элементы, которые нужно пометить
- Добавить проверку ошибок
Не меньше, но, возможно, более надежно?
Этот код проверяет каждый элемент в списке действий, а не ищет присутствие заданных c элементов (1..4):
data want;
set have;
array activities
activities_p1-activities_p3
;
array flags(3,4)
flag_p1_1-flag_p1_4
flag_p2_1-flag_p2_4
flag_p3_1-flag_p3_4
;
do i = 1 to dim(activites);
if missing(activities[i]) then continue; %* skip;
do j = 1 by 1;
item = scan ( activities[i], j, ',' );
if missing(item) then leave; %* no more items in csv list;
item_num = input (item,?1.);
if missing(item_num) then continue; %* skip, csv item is not a number;
if item_num > hbound(flags,2) or item_num < lbound(flags,2) then do;
put 'WARNING:' item_num 'is invalid for flagging';
continue; %* skip, csv item is missing, 0, negative or exceeds 4;
end;
flags (i, item_num) = 1;
end;
* backfill zeroes where flag not assigned;
do j = 1 to hbound(flags,2);
flags (i, item_num) = sum (0, flags (i, item_num)); %* sum() handles missing values;
end;
end;
Здесь та же самая обработка, но только поиск определенных c элементов, которые должны быть помечены:
data have; length id activities_p1-activities_p3 $20;input
id activities_p1-activities_p3 ; datalines;
A 1,2,3,4 1,3 .
B 1,3 1,2,3 1,2,3
C . 1,2,3 1,2,3
D . 1,2,3 .
E 1,2,3 . 1
;
data want;
set have;
array activities
activities_p1-activities_p3
;
array flags(3,4)
flag_p1_1-flag_p1_4
flag_p2_1-flag_p2_4
flag_p3_1-flag_p3_4
;
do i = 1 to dim(activities);
if not missing(activities[i]) then
do j = 1 to hbound(flags,2);
flags (i,j) = sum (flags(i,j), findw(trim(activities[i]),cats(j),',') > 0) > 0;
end;
end;
run;
Что происходит?
- переменные флагов сбрасываются на пропущенные в верхней части шага
hbound
возвращают 4 в качестве верхнего предела второго измерения findw(trim(activities[i]),cats(j),',')
найти позицию j в строке csv trim
, необходимой для удаления конечных пробелов, которые не являются частью findw
списка разделителей слов cats
преобразований число от j до представления символов findw
возвращает позицию j в строке csv. - может также захотеть
compress
пропусков и другого мусора, если значения данных о деятельности ненадежны.
- first
> 0
оценивает положение в 0
j не подарок и 1
подарок - секунда
> 0
- это еще одна оценка логики c, которая гарантирует, что флаг присутствия останется 0
или 1
. В противном случае флаги будут подсчитывать частоту (представьте данные активности 1,1,2,3
)
flags(i,j)
, охватывающие 3 x 4 слота, доступных для пометки.