SAS Do Loop пропускает строки при обработке

У меня есть следующий код. Я пытаюсь проверить абзац (descr) для списка ключевых слов (key_words). Когда я выполняю этот код, журнал считывает все переменные для массива, но проверяет только 2 из 20 000 строк в цикле do (do i=1 to 100 и так далее). Любые предложения о том, как решить эту проблему?

data JE.KeywordMatchTemp1;
  set JE.JEMasterTemp end=eof;
  if _n_ = 1 then do i = 1 by 1 until (eof);
    set JE.KeyWords;
    array keywords[100] $30 _temporary_;
    keywords[i] = Key_Words;
  end;
  match = 0;
  do i = 1 to 100;
    if index(descr, keywords[i]) then match = 1;
  end;
  drop i;
run;

person Tom Anderson    schedule 14.11.2016    source источник


Ответы (1)


Ваша проблема в том, что ваш end=eof находится не в том месте.

Это тривиальный пример расчета «ранга» значения возраста для каждого SASHELP.CLASS респондента.

Посмотрите, где я поставил end=eof. Это потому, что вам нужно использовать его для управления операцией заполнения массива. В противном случае происходит то, что ваш цикл do i = 1 to eof; на самом деле не делает то, о чем вы говорите: он на самом деле не заканчивается на eof, поскольку это никогда не бывает истинным (как это определено в first set утверждение). Вместо этого он завершается, потому что вы выходите за пределы набора данных, а это именно то, чего вы не хотите.

Это то, что делает end=eof: он не позволяет вам попытаться извлечь строку, когда набор данных заполнения массива завершен, что завершает весь шаг данных. Каждый раз, когда вы видите, что шаг данных завершается ровно через 2 итерации, вы можете быть уверены, что проблема, вероятно, заключается в том, что это очень распространенная проблема.

data class_ranks;
  set sashelp.class;   *This dataset you are okay iterating over until the end of the dataset and then quitting the data step, like a normal data step.;
  array ages[19] _temporary_; 
  if _n_=1 then do;
    do _i = 1 by 1 until (eof);   *iterate until the end of the *second* set statement;
      set sashelp.class end=eof;  *see here? This eof is telling this loop when to stop.  It is okay that it is not created until after the loop is.;
      ages[_i] = age;
    end;
    call sortn(of ages[*]);   *ordering the ages loaded by number so they are in proper order for doing the trivial rank task;
  end;
  age_rank = whichn(age,of ages[*]);  *determine where in the list the age falls.  For a real version of this task you would have to check whether this ever happens, and if not you would have to have logic to find the nearest point or whatnot.;
run;
person Joe    schedule 14.11.2016
comment
Благодарю вас! Еще одна вещь, если вы можете. Похоже, что DO-LOOP, который у меня есть во второй части кода, не останавливается при выполнении условия. Любая причина, по которой это может происходить? - person Tom Anderson; 14.11.2016
comment
Не останавливаясь, когда i=100 ? Или не останавливаясь, когда match=1? Последнее не собирается его останавливать, с чего бы это? - person Joe; 14.11.2016