2017-02-22 19 views
1

Мне нужно вычислить движущуюся сумму с 10-дневным выводом в SAS. Я предполагаю, что расширение proc, вероятно, лучший способ сделать это. Я могу сделать это с помощью приведенного ниже кода. Но я хотел бы исключить шаг данных и уменьшить количество строк, используемых в расширении proc, если это возможно.Как создать Moving Sum с помощью Lead с помощью Prco Expand?

proc expand data=averages out=transformed; 

id dt; 

convert x=x_lead_10/transform=(lead 10); 
convert x=x_lead_11/transform=(lead 11); 
convert x=x_lead_12/transform=(lead 12); 
convert x=x_lead_13/transform=(lead 13); 
convert x=x_lead_14/transform=(lead 14); 
convert x=x_lead_15/transform=(lead 15); 
convert x=x_lead_16/transform=(lead 16); 

data formatted; 
set work.transformed; 
x_sum = sum(x_lead_10,x_lead_11,x_lead_12,x_lead_13,x_lead_14,x_lead_15,x_lead_16) 
run; 

У меня есть работы, но я пытаюсь найти более эффективный способ кодировать это. Я делаю это для нескольких переменных, которые заставляют мой код быстро переполняться.

+0

Я не очень хорошо разбираюсь в 'proc expand', но есть несколько опций' transform-sum', которые вы можете использовать здесь: http://support.sas.com/documentation/cdl/en/etsug/ 63939/HTML/default/viewer.htm # etsug_expand_sect026.htm –

+0

Можете ли вы рассказать о том, что вы подразумеваете под 10-дневным линией с перемещающейся суммой. Я заметил, что вы тоже не использовали опцию TRIM, вы изучили это? – Reeza

+0

@Reeza Я пытаюсь получить строку 1, чтобы быть суммой строк с 10 по 16, тогда я хочу, чтобы строка вторая была суммированием или строками с 11 по 17 и т. Д. ... Я не рассматривал вариант TRIM, я Теперь я читаю об этом. Благодарю. – Jarom

ответ

1

Это неточно, но должно помочь вам приблизиться. X_movSum - это значение, которое вы хотите, но не в ячейке, которую вы хотите, это в 11-й строке, которая является суммой предыдущих 10 баллов. EDIT: Теперь это точно, см. Новый код ниже.

В любом случае, вот как ваш код должен быть структурирован и расчет:

*create sample data to work with; 
data random; 
    call streaminit(25); 

    do date='01Jan2016'd to '31Dec2016'd; 
     x=round(Rand('normal', 100, 15), 0.01); 
     output; 
     format date date9.; 
    end; 
run; 

*Modified calculation; 
proc expand data=random out=want; 
    id date; 
     convert x= x_movSum /transformout = (movsum 10 trimleft 9); /*This is the correct calculation expected*/ 
convert x = x_movSumFIRST/transformout = (reverse movsum 10 trimleft 9 reverse);*Correct numbers moved up to first record; 
run; 

* the manual way to do this in a data step. Depending on how much customization you need this may be easier; 
data check; 
    set want; 
    array _t (0:9) _temporary_; 
    _t(mod(_n_, 10))= x; 

    if _n_ > 10 then 
     do; 
      check = sum(of _t(*)); 
     end; 
run;  
+0

MOVSUM действительно то, что я должен был использовать. С этим, как вы сказали, у меня есть правильное значение в неправильной ячейке. Я могу легко сдвинуть это туда, где мне это нужно. Отличное решение. – Jarom

+0

Я обновил свой ответ, я думаю, что второй - это то, что вы хотите, в основном добавьте REVERSE до и после, чтобы он автоматически двигался. – Reeza

0

Просто объединить LEAD преобразование с преобразованием Мовсуму.

convert x=want2/transformout=(lead 10 reverse movsum 7 reverse) ; 

Так что, если ваша серия только 1,2,3, ..... то первое вычисленное значение будет 11 + 12 + 13 + 14 + 15 + 16 + 17 = 98.

+0

Я тоже думал об этом, но он не соответствует вычислениям другого метода. Не знаете, почему, используя SAS 9.4TS1M3. Я попробовал movsum 10 и только с TRIM, MOVSUM/REVERSE. – Reeza

+0

Не соответствует тому, что вы разместили, но соответствует коду, используемому в вопросе. – Tom

+0

Я отправлю полный пример в сообществах SAS. Я не знаю, почему первое число всегда ошибочно ... или даже как оно рассчитывается. Каждое число после матчей, и это мое замешательство. BTW Я предполагаю, что здесь что-то отсутствует, что обычно бывает так: – Reeza