Найдите первое не пропущенное значение str на панели и используйте значение для прямой и обратной заливки по группе (SAS или PROC SQL) - PullRequest
0 голосов
/ 20 сентября 2018

У меня есть набор данных, содержащий несбалансированную панель наблюдений, где я хочу пересылать и обратно заполнять пропущенные и / или «неправильные» наблюдения тикера самой последней не пропущенной строкой.

id time  ticker_have   ticker_want
------------------------------ 
1   1     ABCDE          YYYYY 
1   2     .              YYYYY 
1   3     .              YYYYY 
1   4     YYYYY          YYYYY   
1   5     .              YYYYY
------------------------------
2   4     .              ZZZZZ
2   5     ZZZZZ          ZZZZZ
2   6     .              ZZZZZ
------------------------------
3   1     .              .
------------------------------
4   2     OOOOO          OOOOO
4   3     OOOOO          OOOOO
4   4     OOOOO          OOOOO

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

Пока мне удалось заполнить отсутствующие наблюдениявперед, используя этот код

proc sql;
create table have as select * from old_have order by id, time desc;
quit;

data want;
  drop temp;
  set have;
  by id;
  /* RETAIN the new variable*/
  retain temp; length temp $ 5;
  /* Reset TEMP when the BY-Group changes */
  if first.id then temp=' ';
  /* Assign TEMP when X is non-missing */
  if ticker ne ' ' then temp=ticker;
  /* When X is missing, assign the retained value of TEMP into X */
  else if ticker=' ' then ticker=temp;
run;

Теперь я застрял, выясняя случаи, когда я не могу получить доступ к непропущенному значению, используя last.ticker или first.ticker ...

Какможно ли сделать это с помощью DATA или PROC SQL или любых других команд SAS?

Ответы [ 2 ]

0 голосов
/ 20 сентября 2018

Подумайте об использовании шага данных для извлечения последнего тикера по времени для каждого id , а затем присоединения его к основной таблице.Кроме того, используйте оператор CASE для условного назначения нового тикера, если он отсутствует или нет.

data LastTicker;
    set Tickers (where=(ticker_have ~=""));
    by id;  
    first = first.id;
    last = last.id; 
    if last = 1;
run;

proc sql;
    create table Tickers_Want as
    select t.id, t.time, t.ticker_have, 
           case when t.ticker_have = ""
                then l.ticker_have 
                else t.ticker_have 
           end as tickerwant
    from Tickers t
    left join LastTicker l
        on t.id = l.id
    order by t.id, t.time;
quit;

Данные

data Tickers;
   length ticker_have $ 5;
   input id time ticker_have $;
   datalines;
1   1     ABCDE
1   2     .    
1   3     .    
1   4     YYYYY
1   5     .    
2   4     .    
2   5     ZZZZZ
2   6     .    
3   1     .    
4   2     OOOOO
4   3     OOOOO
4   4     OOOOO
;

Вывод

Obs id  time  ticker_have   tickerwant
1    1     1        ABCDE        ABCDE
2    1     2                     YYYYY
3    1     3                     YYYYY
4    1     4        YYYYY        YYYYY
5    1     5                     YYYYY
6    2     4                     ZZZZZ
7    2     5        ZZZZZ        ZZZZZ
8    2     6                     ZZZZZ
9    3     1    
10   4     2        OOOOO        OOOOO
11   4     3        OOOOO        OOOOO
12   4     4        OOOOO        OOOOO
0 голосов
/ 20 сентября 2018

Вы можете сделать это несколькими способами, но proc sql с некоторыми вложенными подзапросами - это одно из решений.

(Прочтите это изнутри, # 1, затем 2, а затем 3. Вы можете встроить каждый подзапрос всначала набор данных, если это поможет)

proc sql ;
  create table want as 
  /* #3 - match last ticker on id */
  select a.id, a.time, a.ticker_have, b.ticker_want
  from have a
       left join
        /* #2 - id and last ticker */
       (select x.id, x.ticker_have as ticker_want
        from have x
             inner join
              /* #1 - max time with a ticker per id */
             (select id, max(time) as mt
              from have
              where not missing(ticker_have)
              group by id) as y on x.id = y.id and x.time = y.mt) as b on a.id = b.id
  ;
quit ;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...