LesezeichenAbonnierenRSS-Feed abonnieren
mfab
Quartz | Level 8

Hallo zusammen,

 

ich verwende ein Hash, welches ich aus einer bestehenden Tabelle befülle und nutze es, um Informationen an eine Tabelle zu joinen.

Wenn ich definedata() nicht explizit vorgebe, werden die Felder im Ergebnis nicht befüllt.

Daher suche ich nun eine Möglichkeit meine durchnummerierten Felder im definedata() als Variablen-Liste anzugeben. Das scheint allerdings nicht möglich zu sein.

Nachfolgend einige Beispiele, die leider nicht funktionieren (egal, ob mit Hochkommas oder ohne):

  

rc = h_obj.definedata("meineFelder:");
rc = h_obj.definedata("meineFelder_00-meineFelder_24");
rc = h_obj.definedata("_NUMERIC_");
rc = h_obj.definedata("meineFelder-numeric") ;

Hat jemand schon Vergleichbares versucht und eine Lösung dafür gefunden?

 

Besten Dank für Hinweise dazu.

 

Viele Grüße

Michael

 

5 ANTWORTEN 5
GrischaPfister
Fluorite | Level 6

Hallo Michael,

 

laut Dokumentation erwartet definedata() eine kommaseparierte Liste von Variablennamen in einfachen oder doppelten Hochkommata. Du musst die Liste also vorab in eine Makrovariable speichern und in definedata() eine Makrovariable benutzen. Die wird vor Ausführen des Data Step durch die Liste aus der Makroviarable ersetzt und ist dann syntaktisch korrekt: Beispiel aus der SAS-Doku (abgewandelt):

options pageno=1 nodate;

%Let varslist = 'd1', 'd2';

data test;
length d1 8;
length d2 $20;
length k1 $20;
length k2 8;

/* Declare the hash object and two key and data variables */
if _N_ = 1 then do;
   declare hash h();
   rc = h.defineKey('k1', 'k2');
   rc = h.defineData(&varslist);
   rc = h.defineDone();
end;

/* Define constant value for key and data */
k1 = 'Joyce';
k2 = 1001;
d1 = 3;
d2 = 'Ulysses';
rc = h.add();

/* Define constant value for key and data */
k1 = 'Homer';
k2 = 1002;
d1 = 5;
d2 = 'Odyssey';
rc = h.add();

/* Use the OUTPUT method to save the hash object data to the OUT data set */
rc = h.output(dataset: "work.out");
run;

proc print data=work.out;
run;

Hoffe das hilft weiter, viele Grüße,

 

Grischa

mfab
Quartz | Level 8

Hallo Grischa,

 

vielen Dank für Deine Antwort.

 

Ich hatte schon "befürchtet", dass das nicht wie gewünscht möglich ist. In dem Fall nehme ich meist die sashelp.vcolumn zu Hilfe und selektiere die gewünschten Spaltennamen per SQL in eine Variable. Nicht nur, um Code zu sparen, sondern auch um zumindest etwas Generik im Programm zuzulassen. In etwa wie folgt:

proc sql noprint;
  select cats('"',name,'"') into : varlist separated by ',' 
    from sashelp.vcolumn 
   where libname = 'WORK'
     and memname = upcase(&tabelle.)
     and name not in ('NICHT_RELEVANT1', 'NICHT_RELEVANT2')
   ;
quit;

 

Da wir hier innerhalb eines Data-Step sind, hatte ich die Hoffnung, dass eines der Variable-List-Konstrukte funktionieren könnte und einen zusätzlichen Schritt im Programm erspart.

 

Herzlichen Dank und viele Grüße

Michael

Dave_Prinsloo
Calcite | Level 5
Hier ist die Definition von ein Macro von mir, der den Syntax von Macro Tabellen erstellén sehr vereinfacht.   %macro ut_hash_define(  lookuptable      =          /* in: Name der Lookuptabelle (mit Libname) */, lookup_where     =          /* in: Optional Where-Bedingung begrenzt die Sätze die in die Hash-Tabelle geladen werden */, hashobjektname   =          /* in: Optional - Name des Hash-Objektes- needed if the same lookup table is used more than once*/, keys             =          /* in: Liste der Schluesselfelder */, datacols         =          /* in: Liste der Ausgabefelder */, multidata        = N        /* in: Y/N : Duplikaten werden alle beladen, Default =N */, est_rowcount     =          /* in: Geschätze Anzahl Zeilen die in die Hashtabelle geladen wird                                      Sollte leer gelassen werden, wenn &lookuptabelle eine Tabelle einfach geladen wird                                     Angeben wenn a) &lookup_where benutzt wird, oder b) &lookuptable ein View ist,                                      oder c) &lookuptable kein SAS Tabelle, bzw SAS kann                                      die Anzahl Zeilen mit NLOBS nicht abfragen.  Wenn Trotzdem leer aufgerufen wird,                                     wird 100.000 angenommen) */  );

Beispiel Aufruf:
data ok       not_ok(keep=country_cd);set data_with_country;
%ut_hash_define(  lookuptable      =  dimen.countries        , lookup_where     =    effective_dttm lt &rundate.  le '31dec9999'd,     , keys             =          country_cd
, datacols         =          long_desc capital president ruling_party gov_form,, multidata        = N        /* in: Y/N : Duplikaten werden alle beladen, Default =N */  )
rc_find = countries.find();if rc_find ne 0 then output ok;else do;    put 'Country ' country_cd ' not found in lookup table  dimen.countries ';    output not_ok;
end;
run ;

Are you interested in this macro?
RegardsDave Prinsloo
mfab
Quartz | Level 8

Hi Dave,

 

das sieht interessant aus.

Da wir nicht so häufig mit Hashes arbeiten werde ich die Variable mit den Spalten selbst erzeugen.

 

Sollte das häufiger vorkommen, würde ich mir die Option mit einem Macro überlegen.

 

Vielen Dank und viele Grüße

Michael

Patrick
Opal | Level 21

ich verwende ein Hash, welches ich aus einer bestehenden Tabelle befülle

 

Hier ein Loesungsansatz:

data test;
  if _n_=1 then
    do;
      if 0 then set sashelp.class(keep=name _numeric_);
      dcl hash h (dataset:'sashelp.class(keep=name _numeric_)');
      h.defineKey('Name');
      h.defineData(all:'y');
      h.defineDone();
    end;

  name='Alfred';
  h.find();
run;

 

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

Register now!

Diskussionsstatistiken
  • 5 Antworten
  • 1799 Aufrufe
  • 3 Kudos
  • 4 in Unterhaltung