2015-07-07 2 views
1

У меня есть таблица, которая выглядит, как этотTransform пары строк в одну строку

|=========|=====|==================|==============|===========|===========| 
| PREFIX | ID | PREVIOUS_PREFIX | PREVIOUS_ID | VENDOR_1 | VENDOR_2 | 
|=========|=====|==================|==============|===========|===========| 
| A  | 1 |     |    | JAC  |  BOA | 
|---------|-----|------------------|--------------|-----------|-----------| 
| B  | 2 | C    | 99   | LCH  |  GS | 
|---------|-----|------------------|--------------|-----------|-----------| 
| B  | 3 | C    | 99   | LCH  |  JPM | 
|---------|-----|------------------|--------------|-----------|-----------| 

мне нужно, чтобы превратить его в таблицу, которая выглядит, как этот

|=========|=====|==================|==============|===========|===========| 
| PREFIX | ID | PREVIOUS_PREFIX | PREVIOUS_ID | VENDOR_1 | VENDOR_2 | 
|=========|=====|==================|==============|===========|===========| 
| A  | 1 |     |    | JAC  |  BOA | 
|---------|-----|------------------|--------------|-----------|-----------| 
| C  | 99 |     |    | GS  |  JPM | 
|---------|-----|------------------|--------------|-----------|-----------| 

То есть:

  1. Для рядов без PREVIOUS_PREFIX и PREVIOUS_ID он покидает этот ряд, как есть
  2. Для строк с PREVIOUS_PREFIX и PREVIOUS_ID:
    1. он создает новую строку, чей PREFIX такой же, как PREVIOUS_PREFIX, ID является такой же, как PREVIOUS_ID и VENDOR_1 и VENDOR_2 являются производители не общие для исходной пары строк
    2. Она удаляет оригинальные пару строк

ответ

0
/* Create sample data */ 
data have; 
    input Prefix $ ID Previous_Prefix $ Previous_ID Vendor_1 $ Vendor_2 $; 
    cards; 
A 1 . . JAC BOA 
B 2 C 99 LCH GS 
B 3 C 99 LCH JPM 
E 5 F 52 LOK U 
E 5 F 52 LOK M 
    ;;; 
run; 

/* Assign new values for Prefix & ID */ 
data want; 
    set have; 
    if Previous_Prefix ne '' then do; 
     Prefix = Previous_Prefix; 
     Previous_Prefix = ''; 
    end; 
    if Previous_ID ne . then do; 
     ID = Previous_ID; 
     Previous_ID = .; 
    end; 
run; 

/* Merge Vendor_1 & Vender2 into one column */ 
data want2; 
    set want; 
    if first.ID then n = 0; 
    n + 1; 
    by ID notsorted; 
run; 

proc transpose data=want2 out=want3(drop=n _NAME_ rename=(COL1=Vendor)); 
    by Prefix ID n Previous_Prefix Previous_ID; 
    var Vendor_1 Vendor_2; 
run; 

/* Delete common Vendor_ */ 
proc sort data=want3;by Prefix ID Previous_Prefix Previous_ID Vendor;run; 

proc summary data=want3; 
    output out=want4(where=(_freq_ = 1)); 
    by Prefix ID Previous_Prefix Previous_ID Vendor notsorted; 
run; 

/* Transpose data from long back to wide */ 
proc transpose data=want4 out=want5(drop=_:) prefix=Vendor_; 
    var Vendor; 
    by Prefix ID Previous_Prefix Previous_ID notsorted; 
run; 
0

несколько проще было бы расширить одно наблюдение на 2 наблюдения и получить поставщиков в одну переменную и вместе с этим объединить предыдущие_префикс и префикс, чтобы получить new_prefix и аналогично для id. получить данные в этом порядке может решить вашу проблему в одном sql. проверьте этот проект кода.

DATA WANT; 
SET HAVE; 
    PREFIX_NEW =COALESCEC(PREVIOUS_PREFIX,PREFIX); 
    ID_NEW  =COALESCEC(PREVIOUS_ID ,ID); 
IF NOT MISSING(VENDOR_1) THEN VENDOR=VENDOR_1; 
OUTPUT; 
IF NOT MISSING(VENDOR_2) THEN VENDOR=VENDOR_2; 
OUTPUT; 
RUN; 

PROC SQL; 
SELECT PREFIX_NEW 
    , ID_NEW 
    , MIN(VENDOR) AS VENDOR_1 
    , MAX(VENDOR) AS VENDOR_2 
FROM (SELECT PREFIX_NEW 
      , ID_NEW 
      , VENDOR 
      , COUNT(*) AS COUNTER 
     FROM WANT 
     GROUP BY 1,2,3 
     HAVING COUNTER=1 
    ) 
; 
QUIT; 

Надеюсь, это поможет !!!

0

Вы можете достичь этого на одном шаге данных, если ваши данные просты, как вы сказали. Мои предположения состоят в том, что существует только максимум 2 строки с дублирующими префиксами, и всегда есть только два уникальных идентификатора Vendor. Данные также должны быть отсортированы с помощью префикса и идентификатора, если этого уже не сделано.

Основные требования достаточно просты для достижения, используя комбинацию first. и last., чтобы определить, существуют ли повторяющиеся строки префикса и установить требуемые значения. Более сложная часть - логика поставщика, я сделал это, создав временную переменную, чтобы содержать список всех имен, сначала проверяя, существует ли текущее имя. Если это произойдет, оно удалит это имя из списка, иначе оно будет добавлено.

Я добавил много комментариев к коду, чтобы объяснить, что происходит, надеюсь, это довольно ясно. Поскольку в префиксе есть только максимум 2 итерации (я надеюсь), я продублировал пару строк кода, а не создавал do loop.

/* create dummy data */ 
data have; 
input Prefix $ ID Previous_Prefix $ Previous_ID Vendor_1 $ Vendor_2 $; 
datalines; 
A 1 . . JAC BOA 
B 2 C 99 LCH GS 
B 3 C 99 LCH JPM 
; 
run; 

/* transform data */ 
data want; 
set have; 
by prefix id; 
length _vendors $30; /* temporary variable to hold Vendor names */ 
retain _vendors; /* keep values from previous row where necessary */ 
if first.prefix and last.prefix then output; /* if only one Prefix row then output */ 
else do; 
    if first.prefix then call missing(_vendors); /* clear vendor list when Prefix changes */ 
    if index(_vendors, compress(vendor_1)) then _vendors = tranwrd(_vendors,compress(vendor_1),''); /* if Vendor name already exists in list then remove it */ 
     else call catx(',',_vendors,vendor_1); /* else add Vendor name to comma separated list */ 
    if index(_vendors, compress(vendor_2)) then _vendors = tranwrd(_vendors,compress(vendor_2),''); /* repeat previous step for Vendor_2 */ 
     else call catx(',',_vendors,vendor_2); 
    if last.prefix then do; /* for last Prefix record, set the required values and output record */ 
    prefix = previous_prefix; 
    id = previous_id; 
    call missing(previous_prefix,previous_id); 
    vendor_1 = scan(_vendors,1); 
    vendor_2 = scan(_vendors,2); 
    output; 
    end; 
    end; 
drop _vendors; /* drop temporary variable */ 
run; 
Смежные вопросы