Как создать строку Json в SAS

#sas

#sas

Вопрос:

В учебных целях я пытаюсь добиться следующего

Сценарий:

У нас есть поток принятия решений с узлом, содержащим поток правил для проверки правил политики. Правила основаны на логике if-else, где выводом для каждого правила может быть «Отклонить» или «Пересмотреть», например «Правило 602: Если customerAge <18 then Decision = 'Decline' . Мне была предоставлена таблица, содержащая обзор правил политики.

Столбцы в таблице:

  • НОМЕР ПРАВИЛА (значение: например, ‘602’)
  • RULELONGDESC (значение: строка с длинным описанием правила)
  • RULESHORTDESC (значение: строка с кратким описанием правила)
  • RULECANBEOVERRULED (значение: Да / Нет)
  • ПРИОРИТЕТ (значение: 1-44)
  • РЕШЕНИЕ (значение: проверка / отклонение)

При выполнении потока принятия решений нам нужно отправить обратно выходные данные для проверки правил политики в виде строки json. Что-то очень похожее на приведенные ниже примеры:

 DeclineDecision=cats(DeclineDecision,'{','"','RuleNumber','"',':','"',DeclineRuleNumber,'"',',','"','RuleText','"',':','"',DeclineRuleText,'"','},');
ReviewDecision=cats(ReviewDecision,'{','"','RuleNumber','"',':','"',ReviewRuleNumber,'"',',','"','RuleText','"',':','"',ReviewRuleText,'"','},');

ReviewDecision=substr(ReviewDecision,1,length(ReviewDecision)-1);
DeclineDecision=substr(DeclineDecision,1,length(DeclineDecision)-1);
 

Упражнение:
Напишите программу для создания строки JSON.

Моей отправной точкой является таблица правил политики. Исходя из этого, мне нужно создать блок макросов, в котором я подмножествую таблицу на основе правил политики и перебираю с помощью массива для создания строки json.

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

таблица правил

 data policytable;
    infile datalines dlm=',';
    length rulelongdesc ruleshortdesc rulecanbeoverrulled $20. priority 8. decision $12.;
    input rulenumber rulelongdesc$ ruleshortdesc$ rulecanbeoverrulled$ priority decision$;
    datalines;
610,False Application,False,Yes,1,Review
602,Age < 18,Alder,No,1,Decline
639,Unknown address,Adresse,Yes,8,Decline
;
run;
 

Я зашел так далеко. Как я должен продвигаться вперед, чтобы решить эту задачу? Более конкретно, как мне настроить цикл do while для создания строки? На данный момент достаточно вывести строку json с помощью оператора %put.
Должен ли я использовать функцию cats() или catx()? функция substr()?

  %let PolicyString = (602,610,639);
 %macro json;
 /*subsetting data based on rule number (policy string)*/
 data work.testtable (replace=yes);
 set work.policytable;
 where rulenumber in amp;PolicyString;
 run;
 /*use do loop to create json string*/
 %local i;
 %let i=1;

 %do %while(amp;i<4);
 %put i = amp;i;
 %let i = %eval(amp;i 1);
 %end;


 %mend;

 %json;
 

Комментарии:

1. Чтобы уточнить, что вам нужно, вы должны показать некоторые примеры исходных данных и строки JSON, которые вы хотите сгенерировать из этих данных.

2. Привет, Том, спасибо за совет. Я добавил изображение таблицы и вставил в свою программу, которую я написал до сих пор.

3. Привет, Рокоб — то, что ты делаешь, имеет много решений, но ни одному из них не особенно нравится то, что ты показываешь. Можете ли вы объяснить, почему вы вообще пытаетесь использовать язык макросов здесь? Какова конечная цель и каким будет JSON — будет ли он помещен в текстовый файл, или он будет передаваться по протоколу HTTP, или что-то еще? Пока неясно, почему вы не можете использовать PROC JSON, например, для записи JSON, почему вы хотите сделать это вручную?

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

5. Было бы намного проще записать ее во временный файл с помощью PROC JSON, а затем прочитать ее обратно, используя, скажем, шаг данных и оператор filename. Вы застряли с множеством вложенных cats и substrs, если вы создадите ее напрямую.

Ответ №1:

Если вы используете proc json , вы можете записать свою строку во временное местоположение, а затем прочитать ее обратно как макропеременную, содержащую одну длинную строку. Например:

 %let PolicyString = (602,610,639);

filename tmp temp;

proc json out=tmp nopretty nosastags;
    export policytable(where=(rulenumber IN amp;PolicyString.) );
run;

data _null_;
    infile tmp;
    input;
    call symputx('decision_json', _INFILE_);
run;

%put amp;decision_json.;
 

Вывод:

 [{"rulenumber":610,"rulelongdesc":"False Application","ruleshortdesc":"False", ... }]
 

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

Имейте в виду, что макропеременные содержат до 65 534 символов. Если вы не ожидаете, что ваша строка когда-либо приблизится к этому значению, вам не нужно беспокоиться об этом. Если вы это сделаете, вам нужно будет учесть это, либо разделив строку, либо оставив полезную нагрузку JSON во внешнем текстовом файле и отправив ее другим способом, например proc http .

Комментарии:

1. Или используйте proc lua , у которого нет ограничений (кроме доступной памяти). Пример сценария lua для приема JSON: core.sasjs.io/ml__json_8sas.html