У меня частично есть решение, используя запрос объединения в proc sql
, который содержит подзапросы для достижения имени и номера анонимных лиц.
Но, как вы видите, каждый человек вводится вручную в каждый запрос на выбор. Вам не хотелось бы этого делать, если в вашем наборе данных было 200 человек вместо 5, которые вы показываете в примере. Одна из возможностей заключается в том, чтобы запускать запросы на вставку, отражающие запросы выбора объединения:
proc sql;
create table AnonymousReport As
SELECT CASE WHEN t1.name = 'Alice' THEN t1.name ELSE CATS('Person',
(SELECT count(name) + 1 From have t2
WHERE t2.name <= t1.name AND t1.name ne t2.name)) END As RptName,
t1.Col1Number, t1.Col1Pct, t1.Col2Number, t1.Col2Pct, 'Alice' As ReportToWhom
FROM have t1
UNION ALL
SELECT CASE WHEN t1.name = 'Bob' THEN t1.name ELSE CATS('Person',
(SELECT count(name) + 1 From have t2
WHERE t2.name < t1.name AND t1.name ne t2.name)) END As RptName,
t1.Col1Number, t1.Col1Pct, t1.Col2Number, t1.Col2Pct, 'Bob' As ReportToWhom
FROM have t1
UNION ALL
SELECT CASE WHEN t1.name = 'Carol' THEN t1.name ELSE CATS('Person',
(SELECT count(name) + 1 From have t2
WHERE t2.name < t1.name AND t1.name ne t2.name)) END As RptName,
t1.Col1Number, t1.Col1Pct, t1.Col2Number, t1.Col2Pct, 'Carol' As ReportToWhom
FROM have t1
UNION ALL
SELECT CASE WHEN t1.name = 'Dave' THEN t1.name ELSE CATS('Person',
(SELECT count(name) + 1 From have t2
WHERE t2.name < t1.name AND t1.name ne t2.name)) END As RptName,
t1.Col1Number, t1.Col1Pct, t1.Col2Number, t1.Col2Pct, 'Dave' As ReportToWhom
FROM have t1
UNION ALL
SELECT CASE WHEN t1.name = 'Erin' THEN t1.name ELSE CATS('Person',
(SELECT count(name) + 1 From have t2
WHERE t2.name < t1.name AND t1.name ne t2.name)) END As RptName,
t1.Col1Number, t1.Col1Pct, t1.Col2Number, t1.Col2Pct, 'Erin' As ReportToWhom
FROM have t1;
quit;
Данные выходного набора. Отсюда экспортировать индивидуальный отчет каждого человека последним ReportToWhom колонке
RptName Col1Number Col1Pct Col2Number Col2Pct ReportToWhom
Alice 4 15% 8 20% Alice
Person2 8 30% 6 15% Alice
Person3 4 15% 8 20% Alice
Person4 4 15% 8 20% Alice
Person5 4 15% 8 20% Alice
Person1 4 15% 8 20% Bob
Bob 8 30% 6 15% Bob
Person3 4 15% 8 20% Bob
Person4 4 15% 8 20% Bob
Person5 4 15% 8 20% Bob
...
Одним из возможных решений является использование каскадного запрос вставки SQL во всех строках набора данных:
data concat;
set have;
length reptAll $3200;
by name;
retain reptAll;
if first.name then reptAll = "";
unionSQL = "INSERT INTO AnonymousReport (RptName, Col1Number, Col1Pct, Col2Number, Col2Pct, ReportToWhom)
SELECT CASE WHEN t1.name = '" || name || "' THEN t1.name
ELSE CATS('Person', (SELECT count(name) + 1 From have t2
WHERE t2.name <= t1.name AND t1.name ne t2.name)) END As RptName,
t1.Col1Number, t1.Col1Pct, t1.Col2Number, t1.Col2Pct, '" || name || "' As ReportToWhom
FROM have t1";
reptAll = catx('; ', reptAll, unionSQL) ;
call symput('query', reptAll);
if last.name then output;
run;
А затем передать строку в proc sql
макро :
%macro runsql;
proc sql;
&query;
quit;
%mend runsql;
%runsql;
в R, я мог бы сделать это в секундах с петлей paste
/for
/apply
функции, но синтаксис SAS - это другой мир!
Так что код в порядке. Как получить результаты, которые мне нужны? Я очень застрял здесь. Как уже упоминалось, я также буду выводить каждый набор данных человеком. –
Что вы получаете как результат, когда делаете изменения, о которых я упоминал? Пока ваш код выглядит неплохо, только некоторые логические ошибки – kl78
Я возвращаю исходную таблицу «Want». Кажется, что независимо от того, что я делаю, я возвращаю этот стол. –