Как заменить данные из таблицы данными из другой таблицы, аналогично vlookup из Excel? - PullRequest
0 голосов
/ 24 января 2019

Заранее извините за мой плохой английский.

Используя SAS, я пытаюсь подставить данные из одной таблицы, назовем это t1. Чтобы заменить, я сравниваю t1 столбец 1 и t2 столбец 1. Если у меня есть совпадение, я хотел бы использовать значение t2 столбца 2.

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

По какой-то причине я создаю декартово произведение.

proc sql;
    create view 
        v1 as
    select
        t2.c2, (final result)
        t1.c10, (not relevant to problem)
        SUM(t1.c11) (not relevant to problem)
    from 
        _outres.table1 t1
    left join
        _outres.table2 t2
    on 
        t1.c1=t2.c1 (comparing the tables)
    where
        t1.c10= "criteria"
    group by
        t2.c2,
        t1.c10
    ;run;quit;

Если бы это был Excel, я бы решил это так:

Table 1
column 1
A
A
A
B
B
C
C

Table 2
Column 1    column 2
A           AA
B           BB
C           CC

= vlookup (таблица 1, столбец 1, таблица 2, 2, ложь)

Result:
Table 1
column 1
AA
AA
AA
BB
BB
CC
CC

------------------ РЕДАКТИРОВАНИЕ -----------------

@ DCR, это код, который я использовал для проверки на основе вашего ответа. Я внес небольшие изменения, чтобы лучше отражать мои данные и таблицы. Это сработало, как и ожидалось, но мне не удалось перевести это на исходный код.

data tttttt1;
input col1 $ col11 col10 $;
datalines;
A           10           critA
A           12           critA
A           13           critA
A           13           critB
B           11           critA
B           41           critA
B           19           critA
C           20           critA
C           55           critA

;
run;


data tttttt2;
input col1 $ col2 $ ;
datalines;
A           AA
B           BB
C           CC
;
run;

proc sql noprint;
     create table tttttt3 as
            select  b.col2, SUM(a.col11), a.col10
                from (select * from tttttt1) as a
                left join (select * from tttttt2) as b
                    on a.col1 = b.col1
            where a.col10 = "critA"
            group by b.col2, a.col10
;quit;

Ожидаемый и результат были одинаковыми:

AA  35  critA
BB  71  critA
CC  75  critA

Ответы [ 3 ]

0 голосов
/ 25 января 2019

Я думаю, что вы можете искать левое соединение, используя proc sql. Попробуйте следующее:

data t1;
input col1 $ ;
datalines;
A
A
A
B
B
C
C
;
run;

data t2;
input col1 $ col2 $ ;
datalines;
A           AA
B           BB
C           CC
;
run;

proc sql noprint;
     create table t3 as
            select b.col2
                  from (select * from t1) as a
             left join (select * from t2) as b
             on a.col1 = b.col1;
quit;
0 голосов
/ 25 января 2019

Я нашел решение!

Спасибо всем, все ответы, они дали мне некоторое представление.

@ nvioli и @DCR дали мне глубокое понимание. Я работал, чтобы понять декартово произведение, которое я генерировал. Я посчитал количество строк и нашел в результате одинаковое количество строк по сравнению с исходной таблицей t1. Но суммированные значения были явно неверными. Поэтому я понял, что мой код каким-то образом вставлял общую сумму в каждую строку вместо промежуточных итогов «group by».

Я решил это с помощью самого простого решения: я разделил представление на два разных представления. Первый из них будет группировать и суммировать, потому что более старая версия этого кода делала это правильно. Второе представление только оставило бы объединение и изменение данных в простом выборе. Окончательный код выглядит примерно так (упрощенная версия, как в оригинальном примере):

/*view to group and sum columns from t1*/
proc sql;
    create view 
        v1 as
    select
        t1.c1, (column that will be substitute later)
        t1.c10, (not relevant to problem, only to show the "criteria"/group by)
        SUM(t1.c11) (not relevant to problem, only to show sum)
    from 
        _outres.table1 t1
    where
        t1.c10= "criteria"
    group by
        t1.c1,
        t1.c10
    ;quit;run;

После этого:

/*view to substitute the desired column from t1 (now v1) */
proc sql;
    create view 
        v2 as
select
        t2.c2, (column with new data)
        t1.c10, (now already grouped)
        Sum_of_t1.c11 (now already summed)
from 
    v1 
left join
    t2
on
    v1.c1 = t2.c1 (comparing view from t1 with t2)
;quit;run;
0 голосов
/ 24 января 2019

SAS обладает уникальной функцией в виде пользовательских форматов . Формат отображает исходное значение на целевое значение, что очень похоже на VLOOKUP.

Формат связан с переменной с помощью оператора FORMAT.

proc format;
  value $MyFormat
  'A' = 'AA'
  'B' = 'BB'
  'C' = 'CC'
  ;
run;

data have;
  input col1 $ @@; 
  col1_formatted_value = put(col1,$MyFormat.); * typically don't have to do this;
  datalines;
  A A A B B C C D D A
run;

proc print data=have;
  title "Data rendered per attributes associated with variables in data set metadata";
run;
proc print data=have;
  title "col1 Format applied at step time";
  format col1 $MyFormat.;
run;

* col1 format attribute saved with data set;
data have2;
  input col1 $ @@; 
  format col1 $MyFormat.;
  datalines;
  A A A B B C C D D A
run;

proc print data=have2;
  title "Data rendered per format attributes associated with variables (in data set metadata)";
run;

Форматы SAS также могут быть построены непосредственно из данных:

data formatMappingData;
input source $ target $;
fmtname = "$MyFormatFromData";
start = source;
label = target;
datalines;
A AA!
B BB!
C CC!
;
run;

proc format cntlin=formatMappingData;
run;

proc print data=have2;
  title "Data rendered per format attributes associated with variables (in data set metadata)";
  format col1 $MyFormatFromData.;
run;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...