Есть ли способ пометить строки, в которых слово «Добавить» находится в последовательности без каких-либо других слов или пропущенных между ними?
Я попробовал оператор массива с функцией поиска, но не повезло!
Мой вывод будет примерно таким: Добавить Добавить Нет Добавить Нет Добавить -- Отметить Добавить Добавить Добавить Добавить -- Отметить Добавить Добавить Добавить Добавить Добавить . . -- Пометить Мой набор данных составляет 1 миллион записей.
Итак, в вашем примере в строке 1 есть T1 и T2, в строке 2 есть T1 - T6, в строке 3 - T1 - T8? Всегда ли последовательности начинаются с начала? Может ли быть более одной последовательности в строке?
Спасибо за ваш ответ. Да, это так. Они всегда начинают сначала.
Каков ответ на эти три наблюдения в примере ФОТО, который вы опубликовали? В НЕТ НЕТ ДА? Или НЕТ ДА ДА, так как второй запуск начинается с запуска добавления значений. Если второе НЕТ, то было бы ДА, если бы Нет было заменено на Добавить, поскольку теперь есть только Добавить, но с разрывом посередине.
Этот код найдет все последовательности Add
, в которых есть как минимум два Add
подряд, и сохранит все последовательности в одну переменную, разделенную запятыми.
Образец данных:
data have;
input t1$ t2$ t3$ t4$ t5$ t6$ t7$ t8$ t9$ t10$;
datalines;
Add Add No Add No Add . No Add .
Add No Add Add Add Add . . No .
Add Add Add No Add Add Add Add . .
;
run;
Код:
data want;
set have;
array t[*] t:;
array col[10] $;
length sequences $50.;
/* Check if the current and previous value is 'Add' */
do i = 1 to dim(t);
if (i > 1 AND t[i] = 'Add' AND t[i-1] = 'Add') then do;
col[i] = vname(t[i]);
col[i-1] = vname(t[i-1]);
end;
end;
/* Create a comma-separated list for each sequence. For example:
t1-t3,t3-t5
t1-t4
etc.
*/
flag_start = 0;
do i = 1 to dim(col);
/* Find the start of the sequence */
if (col[i] NE ' ' AND NOT flag_start) then do;
seq_start = col[i];
flag_start = 1;
end;
/* Find the end of the sequence */
if (col[i] = ' ' AND flag_start) then do;
seq_end = col[i-1];
flag_start = 0;
end;
/* If we are between sequences, calculate the sequence range and save it */
if (i > 1 AND col[i] = ' ' AND col[i-1] NE ' ') then do;
seq_range = cats(seq_start, '-', seq_end);
sequences = catx(',', sequences, seq_range);
end;
end;
drop i flag_start seq_start seq_end seq_range col:;
run;
Выход:
t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 sequences
Add Add No Add No Add No Add t1-t2
Add No Add Add Add Add No t3-t6
Add Add Add No Add Add Add Add t1-t3,t5-t8
Наличие целевого слова в столбце T<index> можно пометить с помощью двоичного значения, соответствующим образом установив биты.
Пример:
Флаг до 32 столбцов. Для более чем 32 столбцов вам потребуются дополнительные переменные флага и дополнительная бухгалтерия при вычислении значения флага.
data have;
input (t1-t10) ($);
datalines;
Add Add No Add No Add . No Add .
Add No Add Add Add Add . . No .
Add Add Add No Add Add Add Add . .
;
data want;
set have;
array ts t1-t10;
flag = 0;
do over ts;
flag = BOR (flag, BLSHIFT(ts='Add', _i_-1));
end;
format flag binary32.;
run;
У меня есть несколько решений в зависимости от того, когда и сколько последовательностей разрешено.
Во-первых, последовательность определяется как 2 или более последовательных периодов времени с помощью «Добавить». Для своих решений я использовал образцы данных Ричарда.
Решение 1. Действительные последовательности начинаются с T1 до перерыва.
* valid sequence begins at t1 until a break;
data want1;
set have;
length sequence $20;
if t1 = 'Add' and t2 = 'Add'; * if either T1 or T2 <> 'Add' then move on to next obs;
array t(*) t1-t10;
do i = 3 to dim(t); * start loop at t3 since we know t1 & t2 = 'Add';
if t[i] ne 'Add' then do;
sequence = cats('T1-T', put(i-1, 2.));
output;
leave; * exit loop. move to next obs;
end;
end;
drop i;
run;
Результат:
t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 sequence
Add Add No Add No Add No Add T1-T2
Add Add Add No Add Add Add Add T1-T3
Решение 2. Следующее решение по-прежнему обнаруживает допустимые последовательности, начинающиеся с T1, но допускает разрывы и другие последовательности после первой.
* sequence begins at t1 with a break and another sequence occurs on same row;
data want2;
set have;
length sequence $20;
if t1 = 'Add' and t2 = 'Add'; * if either T1 or T2 <> 'Add' then move to next obs;
array t(*) t1-t10;
seq_strt = 1; * start of sequence. start at 1 because of subsetting if;
break = 0; * flag for break in sequence. start at 0 because of subsetting if;
sequence = '';
do i = 3 to dim(t); * start loop at t3 since we know t1 & t2 = 'Add';
* start of sequence - 2 consecutive 'Add' during break;
if break = 1 and t{i] = 'Add' and t[i-1] = 'Add' then do; * start of new sequence;
break = 0;
seq_strt = i-1;
end;
* end of sequence;
else if break = 0 and t[i] ne 'Add' then do;
break = 1; * flag a break;
sequence = catx(',', sequence, cats('T', put(seq_strt, 2.), '-T', put(i-1, 2.)));
end;
end;
drop i seq_strt break;
run;
Результат:
t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 sequence
Add Add No Add No Add No Add T1-T2
Add Add Add No Add Add Add Add T1-T3,T5-T8
Наконец, последнее решение обнаруживает любую последовательность в любой период времени.
* capture any sequence at any period of time;
data want3;
set have;
length sequence $20;
array t(*) t1-t10;
seq_strt = 0; * start of sequence;
break = 1; * flag for break in sequence. start with break until new seq is found;
sequence = '';
do i = 2 to dim(t); * start loop at t2 to compare at t1;
* start of sequence - 2 consecutive 'Add' during break;
if break = 1 and t{i] = 'Add' and t[i-1] = 'Add' then do; * start of new sequence;
break = 0;
seq_strt = i-1;
end;
* end of sequence;
else if break = 0 and t[i] ne 'Add' then do;
break = 1; * flag a break;
sequence = catx(',', sequence, cats('T', put(seq_strt, 2.), '-T', put(i-1, 2.)));
end;
end;
drop i seq_strt break;
run;
Результат:
t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 sequence
Add Add No Add No Add No Add T1-T2
Add No Add Add Add Add No T3-T6
Add Add Add No Add Add Add Add T1-T3,T5-T8
Не внутри массива, хотя вы можете использовать некоторые способы определения последовательностей и длин. Хотя в длинном формате вы могли бы легко. Можете ли вы показать пример того, что вы хотите получить на выходе, и насколько велики ваши данные?