2014-12-19 3 views
1

У меня возник вопрос о создании переменной счетчика с использованием SAS.Подсчет строк по нескольким переменным с использованием SAS

Q R 
---- 
1 a  
1 a 
1 b 
1 b 
1 b 
2 a 
3 a 
3 c 
4 c 
4 c 
4 c 

нужно создать переменную S, который подсчитывает строки, имеет ту же самую комбинацию Q и R. Далее будет выход.

Q  R  S 
------------------- 
1  a  1 
1  a  2 
1  b  1 
1  b  2 
1  b  3* 
2  a  1 
3  a  1 
3  c  1 
4  b  1 
4  b  2 
4  b  3 

Я попытался использовать следующую программу:

данных двух;
set one;
S + 1;
by Q R;
если первый.Q и первый.R then S = 1;
run;

Но это не работает правильно. Например, * выйдет как 1 вместо 3. Я был бы признателен за любые советы о том, как заставить эту переменную подсчета работать правильно.

ответ

3

Очень близко, ваш оператор if должен быть первым. R (или изменить OR и OR, но это не эффективно). Я обычно предпочитаю иметь приращение после множества к 1.

data two; 
set one; 
by Q R; 
*Retain S; *implicitly retained by using the +1 notation; 
if first.R then S = 1; 
else S+1; 
run; 
+0

Спасибо! Это сработало!! – sonicpoem

+0

Ещё один вопрос. Как написать код для вывода любой партии строк с одинаковой комбинацией (в данном случае 1-b и 4-b или любой S> = 3) в качестве набора данных? – sonicpoem

1

например Ризы, конечно достаточно в этом случае, но, учитывая, что это простой вопрос с главным неинтересным ответом, я вместо того, чтобы представить очень маленькие вариант просто с точки зрения стиля программирования.

data two; 
    set one; 
    by Q R; 
    if first.R then s=0; 
    s+1; 
run; 

Это, скорее всего, работать точно так же, как и код Риз и код исходный вопрос после того, как в first.Q удаляется. Однако он имеет две незначительные отличия.

Прежде всего, я хотел бы сгруппировать if first. код с переменным сбросом (который в ином случае не зависит от местоположения) в одном месте, как можно раньше в коде (после инструкций, где «раннее» подмножество, массив, формат, длина и сохранение). Это полезно в организационной точке зрения, потому что этот код (обычно) является тем, что примерно совпадает с тем, что SAS делает между итерациями шага данных, но для групп BY - поэтому приятно иметь его в начале шага данных.

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

Они полезны в более сложной версии этого шага данных; очевидно, на этом конкретном этапе это не имеет большого значения, но на большем шаге данных может быть полезно организовать ваш код более эффективно. Представьте себе этот шаг данных:

data two; 
    set one; 
    by Q R; 
    retain Z; 
    format Z $12.; 
    array CS[15]; 
    if first.R then do; *re-init block; 
    S=0; 
    Z=' '; 
    end; 

    S+1; *increment counter; 

    do _t = 1 to dim(CS); 
    Z = cats(Z,ifc(CS[_t]>0,put(CS[_t],8.),'')); 
    end; 
    keep Q R S Z; 
run; 

Этот шаг данные хорошо организованы, и имеет логический поток, хотя почти каждый шаг может быть перемещен в другом месте в шаге данных. Группировка инициализаций вместе делает ее более читаемой, особенно если вы всегда группировать вещи таким образом.

+0

Порядок, в котором у вас есть ваши утверждения, точно такой же, как и у меня, за исключением того, что иногда вы делаете какие-либо инструкции 'format/length/attrib' перед оператором' set' (по мере необходимости). =) –

+0

Всегда полезно знать более чем один способ решения проблемы. Благодарю. – sonicpoem

Смежные вопросы