Найти ближайшее значение из одной таблицы SAS в другую - PullRequest
0 голосов
/ 16 февраля 2019

возникают проблемы при решении этой проблемы в SAS, вот мои данные:

Таблица A: 3 столбца

ID     COUNT       MEAN

A           2      0.034

B       4     -0.052

C       7      0.327

..  ..  ..

Переменная ID уникальна, а переменная COUNT имеет дискретный диапазон от1-12.

Таблица B: 13 столбцов

CLUSTER  MEAN1  MEAN2  MEAN3  MEAN4  MEAN5  MEAN6  -->   MEAN12

1    0.344  0.234  0.233  ..     ..     ..     ..      ..    

2    0.234  0.234  0.343  ..     ..     ..     ..      ..

Переменная CLUSTER в настоящее время варьируется от 1 до 12, НО ЭТО НЕ ИСПРАВЛЕНО, поэтому код должен иметь возможность включать крайние случаикогда количество кластеров может отличаться.

Проблема: из таблицы A я хочу использовать переменную COUNT в качестве ссылки, чтобы найти ближайший MEAN к списку возможных значений MEAN из соответствующего MEAN (N)из таблицы B, а затем выберите соответствующий номер CLUSTER из строки, связанной с ближайшим совпадением.

Например, идентификатор «A» имеет COUNT, равный 2, и MEAN, равный 0,034, поэтому мне нужно найтисамое близкое среднее значение для этого идентификатора из списка возможных значений MEAN из столбца MEAN2 в таблице B. Мне нужно сделать это для 12 возможных значений COUNT и 12 столбцов MEAN.

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

1 Ответ

0 голосов
/ 17 февраля 2019

Поиск становится намного проще, если вы переставляете кластерные средства в эту компоновкуПример:

* create some sample data for clusters;
data clusters;
  do cluster = 1 to 50;
    array mean(12);
    call missing (of mean(*));
    do _n_ = 1 to ceil(12*ranuni(123));
      mean(_n_) = round(ranuni(123),0.0001);
    end;
    output;
  end;
run;

* create some sample data for observed;
* 60% of the id will be given a mean close to a randomly selected (picked) existing cluster mean;
data observed (keep=id count mean pick flag);
  length id count mean 8.;

  do id = 1 to 1000;
    pick = ceil(50*ranuni(123));

    point = pick;
    set clusters point=point;

    mean = .;

    if ranuni(123) < 0.6 then do until (not missing(mean));
      array means mean1-mean12;
      flag = '*';
      count = ceil(12 * ranuni(123));
      if not missing(means(count)) then 
        mean = means(count) + round((ranuni(123)-0.5) / 1e3,0.0001); 
    end;
    else do;
      flag = 'R';
      count = ceil (12 * ranuni(123));
      mean = round(ranuni(123),0.001) + 0.0005;
    end;

    output;
  end;
  stop;
run;

* use data step to transpose the 'wide' form of cluster data into the 'cluster/count/mean' layout;;
data clusters_tall(keep=cluster count mean);
  set clusters;
  array means mean1-mean12;
  do _n_ = 1 to dim(means) while (not missing(means(_n_)));
    count = _n_;
    mean = means(_n_);
    output;
  end;
run;

* match the observed mean to the closest cluster mean;
* inner join in sub-select is used to get closest cluster, but there could be
* more than one cluster with same closest state.;
* Thus, left join to the sub-select and chose the one
* with the lowest cluster number in case of a tie;

proc sql;
  create table observed_matched(label="Observed matched to cluster with closest mean") as

  select observed.*, matched.cluster, matched.cluster_mean, matched.delta
  from

  observed
  left join 
  ( 
    select 
      id,
      clusters_tall.cluster,
      clusters_tall.mean as cluster_mean,
      observed.mean - clusters_tall.mean as delta
    from 
      observed 
    join 
      clusters_tall 
    on 
      observed.count = clusters_tall.count
    group by 
      observed.id
    having 
      abs(observed.mean - clusters_tall.mean) = min (abs (observed.mean - clusters_tall.mean))
  ) as matched

  on observed.id = matched.id
  group by observed.id
  having cluster = min(cluster)
  order by id, cluster
  ;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...