Вызов SAS SYMPUT - одна макропеременная, два значения? (Условный) - PullRequest
0 голосов
/ 07 января 2019

Я хотел бы создать один макрос с именем "currency_rate", который вызывает правильное значение в зависимости от оговоренных условий (или 'new_rate' или статическое значение 1,5):

%macro MONEY;
%Do i=1 %to 5;

data get_currency_&i (keep=month code new_rate currency_rate);
set Table1;   
if month = &i and  code = 'USD' then currency_rate=new_rate;
else  currency_rate=1.5;
run;

data _null_;
set get_currency_&i;
if month = &i and  code = 'USD' then currency_rate=new_rate;
else  currency_rate=1.5;
call symput ('currency_rate', ???);
run;

%End;

%mend MONEY;

%MONEY

Я доволен циклом do и первым шагом данных. Это вызов, на котором я застрял. Является ли call symput правильной функцией для назначения двух возможных значений одному макросу?

Пример фрагмента того, как я буду использовать 'currency_rate' в процедуре sql:

    t1.income/&currency_rate.          

Я пользователь SAS начального уровня, любое руководство было бы замечательно!

Спасибо

Ответы [ 3 ]

0 голосов
/ 07 января 2019

Давайте смоделируем ваш случай. Предположим, у нас есть 3 datasets, как показано ниже -

data get_currency_1;
    input month code $ new_rate currency_rate;
cards;
1 USD 2 2
2 CHF 2 1.5
3 GBP 1 1.5
;
data get_currency_2;
    input month code $ new_rate currency_rate;
cards;
1 USD 3 1.5
2 USD 4 4
3 JPY 0.5 1.5
;
data get_currency_3;
    input month code $ new_rate currency_rate;
cards;
1 USD 1 1.5
2 USD 3 1.5
3 USD 2.5 2.5
;

Теперь давайте запустим ваш код, где мы присваиваем значение currency_rate.

Пусть i = 1 Итак, набор данных get_currency_1 будет доступен. По мере выполнения шага будет доступен каждый ряд, и значение currency_rate будет присвоено макропеременной currency_rate, и эта итерация будет продолжаться до конца шага данных. В это время последнее значение будет иметь значение currency_rate и будет последним значением макропеременной currency_rate, поскольку после этого шаг заканчивается.

%let i=1;   /*Let's assign 1 to i*/
data _null_;
    set get_currency_&i;
    if month = &i and  code = 'USD' then currency_rate=new_rate;
    else  currency_rate=1.5;
    call symput ('currency_rate', currency_rate);
run;
%put Currency rate is: &currency_rate;
    Currency rate is:          1.5

Пусть i = 3:

%let i=3;   /*Let's assign 3 to i*/
data _null_;
    set get_currency_&i;
    if month = &i and  code = 'USD' then currency_rate=new_rate;
    else  currency_rate=1.5;
    call symput ('currency_rate', currency_rate);
run;
%put Currency rate is: &currency_rate;
    Currency rate is:          2.5

Вы не можете иметь несколько значений для одной макропеременной.

0 голосов
/ 07 января 2019

Вы говорите, что вы новичок, поэтому лучше всего избегать макропрограммирования на этом этапе. Вам будет лучше узнать о where, merge (или join) и by утверждениях.

Вы заявляете, что вам нужно будет использовать currency_rate в выражении, таком как

t1.income / &currency_rate.

Мне t1. подсказывает, что t1 является псевдонимом в соединении SQL, и поэтому гораздо более вероятным сценарием является то, что вам нужно оставить таблицу соединения t1, которая содержит доходы с table1 (назовите его month_datum) содержит месячные курсы валют.

select
  t1.income / coaslesce(monthly_datum.currency_rates,1.5)
, …
from
  income_data as t1
left join
  monthly_datum
on t1.month = monthly_datum.month 

Ставка 1,5 будет использоваться, когда доход связан с месяцем, которого нет в month_datum.

0 голосов
/ 07 января 2019

Макропеременная может содержать только одно значение. Поскольку вы назначаете только одно значение, вы можете легко использовать CALL SYMPUTX ().

 call symputx('currency_rate', currency_rate);

Но если ваши данные имеют более одной строки, тогда это значение будет последним значением, установленным в наборе данных.

...