SAS 9.4 играет с результатами функции IFN - PullRequest
2 голосов
/ 12 марта 2019

Я недавно перешел на SAS 9.4 и обнаружил странную ошибку с функциями IFN и IFC.Пожалуйста, смотрите код ниже, иллюстрирующий функцию IFN:

data a;
input b 8.;
datalines;
0.1
150
110
9.1
1
0

;
run;

proc sql;
create table test as 
select b, (IFN(b = .  | b  > 100 | b  < 1 ,1,0)) as f_no_overlap length = 8,
(IFN(b in (.,0) | b > 100 | b  < 1 ,1,0)) as m_overlap length = 8,
(IFN(b in (.,0) | b  < 1 ,1,0)) as u_no_100,
(IFN(b in (0,110) | b  < 1 | b > 100 ,1,0)) as b_no_null,
(IFN(b = 0 | b  < 1 | b > 100 | b= . ,1,0)) as h_last_miss, 
(IFN(b = . | b = 0 | b  < 1 | b > 100,1,0)) as k_first_null,
(IFN(b = 0 | b = . | b  < 1 | b > 100,1,0)) as y_second_null,
(IFN(b = 0 | b  < 1 | b = . | b > 100,1,0)) as l_third_null,
(IFN(b  < 1 | b = 0 | b = . | b > 100,1,0)) as o_first_one from a;
quit; 

Я получаю следующие результаты: enter image description here

Где, как тот же код на SAS 9.3 дает следующееРезультаты (что правильно): enter image description here

Почему он ведет себя так странно при тех же условиях на 9.4, в основном это NULL в состоянии, которое, кажется, вызываетвопрос.Кто-нибудь сталкивался с такой же проблемой?У нас есть решение для этого?

Ответы [ 2 ]

3 голосов
/ 12 марта 2019

Обсуждение неожиданных результатов оценки относится к коду, выполненному в SAS 9.4 TS1M4 в Windows 10.0.17763, сборка 17763.

3    proc options;
4    run;

    SAS (r) Proprietary Software Release 9.4  TS1M4

В SQL отсутствует концепция отсутствующего значения (., .<letter>), как в DATA Step и других процессах. SQL имеет NULL, а SAS принудительно пропускает значения в NULL, поэтому существует нечеткое ребро, и вы обнаружили там проблему!

Похоже, что неправильная оценка выражения заключается в том, как реализация 9.4 SQL обрабатывает пропущенные литеральные (.) значения в данном конкретном случае. Ошибка не в IFN, а в оценке, переданной IFN!

Изучение только логического выражения проблем, похоже, не связано с IN. Подобные неожиданные результаты оценки возникают, когда IN разбивается на серию OR с. Конкретная причина заключается в том, что в выражении появляется отсутствующий литерал (.), который в свою очередь становится 9.4 внутренними реализациями SQL (анализ и т. Д.)

Определенно кажется ошибкой, когда более двух подвыражений и одно из них использует пропущенное (.). Надлежащим средством, которое станет более подходящим для удаленной или сквозной обработки, будет исключение использования отсутствующих литералов (.) в вашем SQL и использование операторов нулевых тестов ANSI IS NULL и IS NOT NULL

data have;
  b = 9.1;
run;

proc sql;
  create table want as
  select 
  b
  , b in (.,0) | b > 100                      as part1                        /* correct result */
  , b in (.,0)           | b < 1              as part2                        /* correct result */
  ,              b > 100 | b < 1              as part3                        /* correct result */
  , b in (.,0) | b > 100 | b < 1              as parts_null_first             /* INCORRECT result */
  ,              b > 100 | b < 1 | b in (.,0) as parts_null_last              /* INCORRECT result */
  , b=. | b=0  | b > 100 | b < 1              as parts_no_in_null_first       /* INCORRECT result */
  ,       b=0  | b > 100 | b < 1 | b= .       as parts_no_in_null_last        /* correct - weird? */

  , b is null | b=0 | b > 100 | b < 1 as parts_is_null                        /* correct result */

  , calculated part1 | calculated part2 | calculated part3 as calc_parts_in_1_expr /* correct result */

  from have
  ;
quit;

Я не проверял, возникает ли такая же проблема, когда проблемное выражение находится в каллусе WHERE. Выражение не является проблемой в качестве присваивания на шаге DATA:

data want2;
  set have;
  parts_null_first = b in (.,0) | b > 100 | b < 1 ;                 /* correct result  */
  parts_null_last  =              b > 100 | b < 1 | b in (.,0);     /* correct result */
run;

Если в выражениях «где» выражения возникает «ошибка» выражения, то механизм оценки «где» является более вероятной основной причиной - я считаю, что этот же механизм используется для операторов Proc / Data WHERE, Dataset WHERE = опция и SQL-вычислений.

Может быть SAS Note или Hotfix для ситуации, но я не пошел искать.

Еще одно обсуждение проверки пропущенных значений можно найти в SAS_Tipster: "Совет SAS: используйте IS MISSING и IS NULL с числовыми или символьными переменными" на community.sas.com. Важным недостатком является использование операторов в тестировании критериев для нулевых значений.

Операторы IS MISSING и IS NULL, которые используются с оператором WHERE, могут обрабатывать символьные или числовые переменные. Они также работают с оператором NOT:

Документация Суммирует IS MISSING predicate как:

Проверка отсутствия значения SAS в собственном хранилище данных SAS.

0 голосов
/ 01 апреля 2019

SAS вернулся с этим ответом:
Мы выпустили примечание к проблеме XXXXXX: Проблема с функцией IFN в SAS 9.4TS1M4 в связи с этой проблемой.Похоже, что единственным решением на этом этапе является обновление до более новой версии SAS, такой как SAS 9.4M5 (TS1M5) или более поздней.поэтому на данной стадии нет исправления или решения для этой проблемы в текущей версии.

...