Сохранить выписку в SAS

вот что у меня есть в качестве набора данных:

****************
* name * value *
*  x   *   #   *
*  x   *   .   *
*  x   *   .   *
*  x   *   .   *
*  y   *   .   *
*  y   *   #   *
*  y   *   .   *
*  y   *   .   *
*  z   *   .   *
*  z   *   .   *
*  z   *   #   *
*  z   *   .   *
*  z   *   .   *
*  z   *   #   *
****************

Что я пытаюсь сделать, так это сохранить числа (#) до конца строки каждого имени. Результат будет следующим:

****************
* name * value *
*  x   *   #   *
*  x   *   #   *
*  x   *   #   *
*  x   *   #   *
*  y   *   .   *
*  y   *   #   *
*  y   *   #   *
*  y   *   #   *
*  z   *   .   *
*  z   *   .   *
*  z   *   #   *
*  z   *   #   *
*  z   *   #   *
*  z   *   #   *
****************

. остается, потому что для этой точки нет данных. Мне просто нужно заполнить строки, в которых у меня есть данные.

До сих пор у меня был код, который выглядел так:

DATA test;
  SET test;
  retain _variable;
  if not missing(variable) then _variable=variable;
  else variable=_variable;
  drop _variable;
RUN;

Это не работает, потому что # последнее значение x переносится на первое значение y. Я подумал об использовании функции do until last.variable. Но я не смог заставить его работать.

Пожалуйста помоги.


person gbarbe77    schedule 13.01.2016    source источник


Ответы (4)


Вы были очень близки. Вместо этого используйте оператор retain для новой переменной с именем _value и сбрасывайте ее в начале каждой группы name. В конце отбросьте исходный value, затем переименуйте _value обратно в value, используя опцию шага данных.

DATA want(rename=(_value = value) );
  SET have;
  by name;

  retain _value;

  if(NOT missing(value) ) then _value = value;

  output;

  if(last.name) then call missing(_value);

  drop value;
RUN;
person Stu Sztukowski    schedule 13.01.2016
comment
Отличная работа! Спасибо за своевременный ответ. Работает как часы. - person gbarbe77; 14.01.2016

Вы можете рассмотреть трюк UPDATE. У него есть качества, которые вы ищете, плюс он будет LOCF все переменные.

data value;
   input (name value value2)(:$1.);
   cards;
 x      #     $
 x      .     @ 
 x      .     . 
 x      .     . 
 y      .     $
 y      #     .
 y      .     @
 y      .     .
 z      .     .
 z      .     .
 z      #     $
 z      .     .
 z      .     .
 z      #     @
 ;;;;
   run;
proc print;
   run;
data locf;
   update value(obs=0) value;
   by name;
   output;
   run; 
proc print;
   run;

введите здесь описание изображения

person data _null_    schedule 14.01.2016
comment
Это действительно умно! У вас есть официальный документ, где я могу подробнее узнать о том, как это работает? - person Stu Sztukowski; 14.01.2016
comment
lexjansen.com/pharmasug/2013/BB/PharmaSUG-2013- BB10.pdf Где я пытаюсь объяснить, как это работает. - person data _null_; 14.01.2016
comment
Ты жжешь. Благодарю вас! - person Stu Sztukowski; 14.01.2016

Закажите свой набор данных по имени.

Затем:

data want;
set have;
by name;
retain new_value;

if value ne . then new_value = value;
output;
if last.name then new_value = .;
run;

После вывода мы проверяем, является ли это фамилией, если это так, мы устанавливаем новое_значение в отсутствующее, поэтому в следующем вводе из оператора set мы можем получить номер, если он есть.

person RamB    schedule 13.01.2016
comment
Большой! Оба ваших ответа работают! Спасибо за своевременные ответы. - person gbarbe77; 14.01.2016

В качестве альтернативы вы можете пропустить его в начале шага данных, чтобы избежать необходимости в операторе OUTPUT:

data want(drop = temp);
set have;
by name;
retain temp;

if first.name then temp = .; /* reset */

if value ne . then temp = value;
else if value eq . then value = temp;

run;
person user5072412    schedule 14.01.2016