Hallo zusammen,
für eine Verteilung von Daten habe ich die Anforderung das eine Tabelle auf verschiedene Tabellen, deren Anzahl je nach enthaltenen Gruppen variieren kann, aufgeteilt werden muss.
Hier habe ich auch einen Code der funktioniert:
data WORK.CLASS;
infile datalines dsd truncover;
input Name $9. Group $1.;
datalines;
Alfred A
Alice B
Barbara B
Carol C
Henry C
Paul D
;
run;
%MACRO gruppen(datei1, pool);
PROC SQL NOPRINT;
SELECT DISTINCT &pool INTO :pools SEPARATED BY ' '
FROM &datei1;
QUIT;
%DO i=1 %TO &SQLOBS;
%LET group=%SCAN(&pools, &i);
%PUT &i: *&group*;
proc sql noprint;
select distinct count(*) into :Menge TRIMMED from &datei1 where &pool = "&group"
group by &pool;
quit;
proc sql;
create table &group._&Menge._Ende as select * from &datei1 where &pool = "&group" ;
quit;
%END;
%MEND;
%gruppen(WORK.class, group);
nun mein Problem:
Wenn die Menge in den einzelnen Gruppen einen bestimmten Wert unterschreitet sollen diese Gruppen automatisch zu einer Tabelle zusammengefasst werden.
In den Beispieldaten oben sollten die gruppen A + D zu einer Tabelle zusammengefasst sein und die Gruppen B und C jeweils in einer eigenen Tabelle stehen.
Danke für eure Unterstützung!
Viele Grüße
Bernd
Ein Vorschlag:
data work.have;
infile datalines dsd truncover;
input Name $9. Group $1.;
datalines;
Alfred A
Alice B
Barbara B
Carol C
Henry C
Paul D
;
proc summary data=work.have nway;
class Group;
output out= work.Size(drop= _type_ rename=(_freq_=count));
run;
%global schwelle;
%let schwelle = 2;
data work.ReGroup;
set work.Size end=jobDone;
length
Dataset $ 42
DatasetList $ 4200
;
retain DatasetList;
Dataset = catx('_', ifc(count < &schwelle., 'ZZZ', Group), Count, 'Ende');
if index(DatasetList, trim(Dataset)) = 0 then DatasetList = catx(' ', DatasetList, Dataset);
if jobDone then call symputx('datasetList', DatasetList);
drop DatasetList;
run;
data _null_;
set work.ReGroup end= jobDone;
if _n_ = 1 then do;
call execute(cat('data ', "&datasetList.", ';'));
call execute('set work.have;');
call execute('select (Group);');
end;
call execute(catx(' ', 'when (', quote(trim(Group)), ') output', Dataset, ';'));
if jobDone then do;
call execute('end; run;');
end;
run;
Hallo @Spinner_Bernd,
in dem Beispiel liegt es nahe, die Gruppen A und D zusammenzufassen -- wenn man 2 als den "bestimmten Wert" annimmt, den die Gruppengrößen hier unterschreiten. Weniger eindeutig würde es aber schon, wenn nur ein weiterer Satz mit Group='D' hinzukäme. Dann müsste der Satz mit Group='A' einer der drei anderen Gruppen zugeschlagen werden. Aber welcher? Würde z. B. Gruppe C bevorzugt, wenn B und D bereits drei Sätze enthielten, C aber nur zwei? Was wäre, wenn es weitere Gruppen E, F, ..., Z mit je einem Satz gäbe? Allein auf Basis der Regel, mindestens zwei Sätze in einer Ausgabetabelle zu haben, könnte man diese alle zu einer großen Tabelle zusammenfassen. Ich vermute aber, dass andere, noch nicht genannte Regeln dagegensprechen.
Wie viele Sätze und wie viele Gruppen kann die aufzuteilende Tabelle enthalten? Wenn die Anzahlen hinreichend groß sind und unter vielen kombinatorisch möglichen Aufteilungen eine "optimale" gesucht ist (etwa eine möglichst "gleichmäßige"), könnten Methoden aus dem Modul SAS/OR erforderlich sein (das aber in meiner SAS-Lizenz nicht enthalten ist).
Hallo @FreelanceReinh
die Ursprungstabelle ist variabel sie schwankt Erfahrungsgemäß zwischen 200 und 5000 Datensätzen und wird momentan auf bis zu 40 Gruppen aufgeteilt, um diese Anzahl zu reduzieren suche ich jetzt nach einer Lösung, die alle Kleinstmengen zu einer Gruppe zusammenfasst. Daher auch die Beispieldaten mit zwei Gruppen mit einem Datensatz und zwei Gruppen mit zwei Datensätzen.
Es soll nicht möglichst gleichmäßig aufgeteilt werden, sondern nach einem bestimmten Merkmal wird eine Gruppe gebildet und als seperate Tabelle gespeichert um dann in einem weiteren System weiterverarbeitet zu werden.
Viele Grüße
Bernd
Moin Bernd!
Da fehlen noch ein paar Kleinigkeiten in deiner Beschreibung:
Hallo Andreas,
es geht darum iKleinstmengen nach einer Aufteilung zusammenzufassen, in den Beispieldaten wäre das momentan 1 Datensatz, in den Realdaten wird es wohl auf einen Wert von 5-10 rauslaufen ( der Wert wird aber definitiv für alle Gruppen gleich sein)
Entscheidend ist nur die Menge in der einzelnen Gruppe um die Gruppe entweder seperat zu lassen oder zu einer Sammelgruppe zusammenzufassen
Alles unter Schwellwert => eine Sammeltabelle
Alles über dem Schwellwert => je Gruppe eine Tabelle
Viele Grüße
Bernd
Ein Vorschlag:
data work.have;
infile datalines dsd truncover;
input Name $9. Group $1.;
datalines;
Alfred A
Alice B
Barbara B
Carol C
Henry C
Paul D
;
proc summary data=work.have nway;
class Group;
output out= work.Size(drop= _type_ rename=(_freq_=count));
run;
%global schwelle;
%let schwelle = 2;
data work.ReGroup;
set work.Size end=jobDone;
length
Dataset $ 42
DatasetList $ 4200
;
retain DatasetList;
Dataset = catx('_', ifc(count < &schwelle., 'ZZZ', Group), Count, 'Ende');
if index(DatasetList, trim(Dataset)) = 0 then DatasetList = catx(' ', DatasetList, Dataset);
if jobDone then call symputx('datasetList', DatasetList);
drop DatasetList;
run;
data _null_;
set work.ReGroup end= jobDone;
if _n_ = 1 then do;
call execute(cat('data ', "&datasetList.", ';'));
call execute('set work.have;');
call execute('select (Group);');
end;
call execute(catx(' ', 'when (', quote(trim(Group)), ') output', Dataset, ';'));
if jobDone then do;
call execute('end; run;');
end;
run;
Danke Andreas!
Dein Code macht genau das was ich wollte 😊
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!