2015-05-19 3 views
1

У меня есть таблица, которая очень напоминает следующий формат:Накопленная Ежемесячный Percentile Расчет в SAS PROC SQL

ID | Month_ID | Param1 | Param2 
1 | 1  | 5 | 10 
1 | 1  | 6 | 12 
1 | 2  | 4 | 9 
1 | 2  | 8 | 15 
2 | 1  | 3 | 17 
2 | 1  | 5 | 12 
2 | 2  | 3 | 11 
2 | 2  | 6 | 10 

Мне нужно вычислить несколько процентили (50, 75, 85, 90, 95) для param1 и param2 по ID и month_id, однако для каждого месяца мне нужно включить все данные за предыдущие месяцы (так что month_id = 2 вычислил процентили для param1 и param2, используя данные from month_id = 1 AND month_id = 2). Я попытался с помощью proc univariate, но я могу понять только, как получить его для каждого месяца со следующим кодом:

proc univariate data=table noprint; 
by ID Month_ID NOTSORTED; 
var param1 param2; 
output out=Pctls pctlpts = 50 75 85 90 95 
       pctlpre = param1_ param2_ 
       pctlname = pct50 pct75 pct85 pct90 pct95; 

run; 

Кто-нибудь знает способ вычисления этих процентили накапливая месяцев? Заранее спасибо!

ответ

0

Это должно работать с пользовательскими диапазонами месяца (хотя предполагается, что месяцы все присутствует между мин и макс для каждого ID):

пустышки данные с различными диапазонами месяц:

data input ; 
    do ID=1 to 2 ; 
    do month_id=3+ID to 20-ID*2 ; 
     parm1=int(ranuni(1)*100) ; 
     parm2=int(ranuni(1)*100) ; 
     output ; 
    end ; 
    end ; 
run ; 

Определение минимального и максимального месяц для каждой группы идентификаторов:

proc sql ; 
create table range as 
    select *, min(month_id) as minmonth, max(month_id) as maxmonth 
    from input 
    group by ID 
    order by ID, month_id 
;quit ; 

Выходной каждый месяц в соответствующие группы:

data output ; 
    set range ; 
    by ID ; 
    do group=month_id to maxmonth ; 
    output ; 
    end ; 
run; 
+0

Это выглядит хорошо. Затем я разделил бы мой одноклассник по ID и группе? – Y0dle

+0

Да, это правильно – Bendy

+0

Вы получили результат, по которому вы были? Если вы счастливы, что он решает вашу проблему, пожалуйста, примите это как ответ – Bendy

1

Я не могу придумать способ сделать это непосредственно в прок одномерный, но я бы, вероятно, расширить и перегруппировать данные, как показано ниже:

*dummy data ; 
data input ; 
    do ID=1 to 2 ; 
    do month_id=1 to 12 ; 
     parm1=int(ranuni(1)*100) ; 
     parm2=int(ranuni(1)*100) ; 
     output ; 
    end ; 
    end ; 
run ; 


data expand ; 
    set input ; 
    do group=12 to 1 by -1 ; 
    if month_id le group then output ; 
    end ; 
run ; 

Это то дает переменную группа, где группа = 1 содержит только месяц1, группа = 2 содержит месяц1 и месяц2 и т. д.

+0

Мне нравится этот подход, кроме моего month_id не то, что вы бы предположить, что это. Это в основном количество месяцев между самой низкой датой в наборе данных до даты данной строки, поэтому она может превышать 12. Кроме того, не все идентификаторы имеют данные за все месяцы (поэтому один идентификатор может начинаться с month_id = 5 и перейдите к month_id = 21, а другой может начинаться с 2 и идти до 4). – Y0dle

+0

Привет @ Y0dle, я добавлю еще один ответ, а не обновляю приведенный выше ответ, если он будет полезен для кого-либо еще, как попробует что-то еще ... – Bendy

0

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

data accum_table; 
    set table; 
    by ID Month_ID; 
    if first.ID then call missing (Accum1, Accum2); 
    Accum1+Param1; 
    Accum2+Param2; 
    if last.Month_ID then output; 
run; 
+0

Что мне делать с накопленными параметрами? Наверное, я не понимаю, как это поможет мне рассчитать процентиль. – Y0dle

+0

Для новых данных вы будете запускать однопроцессорный процесс. – Jeff