2016-06-20 4 views
0

Это мой первый вопрос, задающий вопрос на этом форуме. Я использовал SAS/Proc SQL около 4 лет, но я не являюсь кодовым джедаем, поэтому, пожалуйста, дайте подробные ответы и достаточно новый для массивов, поэтому прощайте, если мой вопрос плохо детализирован/объяснен. Я на 100% удобнее строить/использовать простые массивы в целом. Но у меня есть очень специфический вызов, который я не могу понять ... Трудно выразить словами, так что это может затянуться, но здесь идет ...Переменная итерации массива SAS

Для базового понимания того, что я пытаюсь выполнить, это несколько аналогично простой амортизации кредита, где месяц 1 баланс является первоначальной суммой кредита, скажем, 10 000 долларов США, 2-й месяц, баланс - orig_ln_amt за вычетом любого нового основного/процентного платежа за вычетом любого дополнительного платежа, в результате чего можно сказать, что 9500 долл. США, 3 месяца - 9000 долл. США и т. д. .... Легко для 1 учетной записи, но я строю массив, который фактически дает прогнозируемый общий оставшийся остаток, когда все активные учетные записи свертываются вместе для каждого месяца в будущем, поэтому я использую массив, который изменяется в размере каждый месяц в зависимости от возраста счетов.

Вот пример кода, который я надеялся, что будет работать:

DATA SAMPLE; 
    SET INPUT_DATA; 'HAS EACH OF THE 3 INPUT ARRAYS LAID OUT SIDE BY SIDE BY SIDE 
    ARRAY_ONE {193} ARRAY_ONE1-ARRAY_ONE193; 
    ARRAY_TWO {97} ARRAY_TWO1-ARRAY_TWO97; 
    ARRAY_THREE {97} ARRAY_THREE1-ARRAY_THREE97; 
    OUTPUT_ARRAY {193} OUTPUT_ARRAY1-OUTPUT_ARRAY193; 'PORTFOLIO BALANCE EACH FUTURE MONTH 
    DO I = 1 TO 193; 
    OUTPUT_ARRAY[I] = sum(of ARRAY_ONE[I]-ARRAY_ONE193) - sum(of ARRAY_TWO[I]-ARRAY_TWO97) - sum(of ARRAY_THREE[I]-ARRAY_THREE97); 
    END; 
RUN; 

Проблема заключается в SAS не нравится [I [ссылка итерации внутри вычисления массива. Я также попробовал & Я основал на решении другого онлайн-пользователя, полученного в том, что, похоже, было аналогичной проблемой. Логика имеет смысл, и кажется, что она должна работать в теории, но не ...

Таким образом, мы должны были вручную манипулировать и код каждого из 193 расчетов:

OUTPUT_ARRAY1 = sum(of ARRAY_ONE1-ARRAY_ONE193) - sum(of ARRAY_TWO1-ARRAY_TWO97) - sum(of ARRAY_THREE1-ARRAY_THREE97); 
OUTPUT_ARRAY2 = sum(of ARRAY_ONE2-ARRAY_ONE193) - sum(of ARRAY_TWO2-ARRAY_TWO97) - sum(of ARRAY_THREE2-ARRAY_THREE97); 
    ... 
OUTPUT_ARRAY97 = sum(of ARRAY_ONE97-ARRAY_ONE193) - sum(of ARRAY_TWO97-ARRAY_TWO97) - sum(of ARRAY_THREE97-ARRAY_THREE97); 
OUTPUT_ARRAY98 = sum(of ARRAY_ONE98-ARRAY_ONE193); 
    ... 
OUTPUT_ARRAY193 = sum(of ARRAY_ONE193-ARRAY_ONE193); 

Похоже, что там должно быть легким решением, но мы не можем понять это. Заранее благодарим за любую помощь, которую вы можете дать всем.

+1

Отдельно от ответа на ваш вопрос: Я бы * сильно * призываю вас переформулировать вашу структуру данных. SAS (и любой другой нематричный язык) будет делать _Far_ лучше, если у вас есть одна строка за период времени здесь. – Joe

+0

Что содержится в массивах? Балансы? Интерес? Разные месяцы? Почему разные длины? Отправьте фрагмент данных. Я вижу комплексное решение SQL-запросов. – Parfait

+0

Хорошие вопросы ... Немного сложно ответить, потому что мой пример погашения кредитов не является идеальным сравнением, и он становится немного грязным в деталях.Выход = оставшийся баланс (гаснет 193 мс); Array1 = Bross Loss $ (193mos); Array2 = Выплаты (97mos); Array3 = Регулярные платежи (97mos). Массивы различной длины, потому что есть другие события, которые происходят в течение жизни портфеля ... – CraigD

ответ

1

Переменные списки, такие как VAR1-VAR20, вычисляются при компиляции шага данных. Ваша попытка использовать ARRAY[I]-variable193 в качестве списка переменных не собирается летать. Просто используйте другую петлю DO.

DO I = 1 TO dim(output_array); 
    output_array(i)=0; 
    DO J=I to dim(array_one); 
    output_array(i)= sum(output_array(i),array_one(j)); 
    END; 
    DO J=I to dim(array_two); 
    output_array(i)= sum(output_array(i),array_two(j)); 
    END; 
    DO J=I to dim(array_three); 
    output_array(i)= sum(output_array(i),array_three(j)); 
    END; 
END; 
+0

О, я совершенно неправильно понял, что он там делает. Хорошая точка зрения. – Joe

+0

Вы можете по-прежнему хотеть проверять dims массива two/three, так как они короче, чем один массив. – Joe

+0

Таким образом, отдельные петли для каждого входного массива. – Tom

2

Таким образом, у вас есть три набора переменных с принципиальными корректировками. У вас есть начальный баланс, и вы хотите рассчитать различные промежуточные балансы, применяя корректировки.

Сначала упростите вашу проблему, создав массивы того же размера. Новые переменные будут отсутствовать. Если у вас есть эти переменные, но просто не хотите включать их в вычисления, то отбросьте их из входного набора данных. Обратите внимание, что если у вас есть переменные с именем ONE1 - ONE193, вы можете создать массив с именем ONE, который использует эти переменные, просто используя это выражение array one(193);.

Во-вторых, упростите вашу арифметику, чтобы более точно соответствовать описанию вашей проблемы. Мне кажется, что алгоритм состоит в том, что следующий баланс основан на предыдущем балансе минус все корректировки. Включите ноль, чтобы обработать случай, когда отсутствуют значения для всех настроек.

%let n=193; 
data want; 
    set have; 
    array one (&n); 
    array two (&n); 
    array three (&n); 
    array balance Initial_balance balance1-balance&n; 
    do i=1 to dim(balance)-1; 
    balance(i+1)=balance(i)-sum(0,one(i),two(i),three(i)); 
    end; 
run; 
+0

Спасибо, Том. это почти то, что я придумал, и результаты привязаны к старому коду ... Цените свою помощь очень! – CraigD

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