Webinar@Lunchtime Effizientes Programmieren mit Suchtfaktor: SAS Hash-Tables
Copy rig ht © SA S Institute Inc. A ll rig hts re se rve d.
Table Lookup Technik: Hash Tables Werte aus einer Referenztabelle abfragen mittels Hash Tables
DATA Step Hash Objekte: Eigenschaften
Datenspeicherung und Suche im Arbeitsspeicher Hash Objekt muss in den Arbeitsspeicher passen (kleinere Datei nehmen) Schnelle Alternative zu Data Step Merge oder SQL Joins Anders als bei Arrays können verschiedene Datentypen zusammen in einem Objekt sein Daten müssen nicht sortiert sein Nutzt den Schlüssel für eine schnelle Datensuche Dot-Net Syntax (objektorientiert)
Copy rig ht © SA S Institute Inc. A ll rig hts re se rve d.
Szenario Die Datei orion.supplier beinhaltet demographische Informationen über Lieferanten (keine Produktinfos). Teilauszug aus der Datei: orion.supplier Supplier_ ID
Supplier_Name
Street_ ID
Supplier_Address
Sup_ Street_N umber
Country
50
Scandinavian Clothing A/S
6850100389
Kr. Augusts Gate 13
13
NO
109
Petterson AB
8500100286
Blasieholmstorg 1
1
SE
316
Prime Sports Ltd
9250103252
9 Carlisle Place
9
GB
755
Top Sports
3150108266
Jernbanegade 45
45
DK
9260115819
553 Cliffview Dr
553
US
. . .
. . .
. . .
772 . . .
AllSeasons Outdoor Clothing . . .
. . .
Copy rig ht © SA S Institute Inc. A ll rig hts re se rve d.
Szenario Es müssen Daten aus der Datei orion.supplier mit orion.product_list verbunden werden, welche Produktinformationen beinhaltet. Teilauszug aus der Datei: orion.product_list Product_ID
Product_Name
Supplier_ ID
Product_ Level
Product_ Ref_ID
210000000000
Children
.
4
.
210100000000
Children Outdoors
.
3
210000000000
210100100000
Outdoor things, Kids
.
2
210100000000
210200000000
Children Sports
.
3
210000000000
210200100000
A-Team, Kids Kids Sweat Round Neck,Large Logo
.
2
210200000000
3298
1
210200100000
. . .
. . .
. . .
210200100009 . . .
. . .
Copy rig ht © SA S Institute Inc. A ll rig hts re se rve d.
Ein Hash Objekt aus einer SAS Datei befüllen data supplier_info; length Supplier_Name $40 Supplier_Address $ 45 Country $ 2; if _N_=1 then do; declare hash S(dataset:'orion.supplier'); S.definekey('Supplier_ID'); S.definedata('Supplier_Name', 'Supplier_Address','Country'); S.definedone(); call missing(Supplier_Name, Supplier_Address,Country); end; set orion.product_list; rc=S.find(); if rc=0; drop rc; run; Copy rig ht © SA S Institute Inc. A ll rig hts re se rve d.
Hash Objekt erstellen Erstellen eines Hash Objekts namens T.
declare hash T();
Erstellen des T Hash Objekts und Laden aus der Datei orion.MemberType.
declare hash T(dataset: 'orion.MemberType');
Copy rig ht © SA S Institute Inc. A ll rig hts re se rve d.
Ausführung Auszug: HASH Object S KEY: Supplier _ID
DATA: Supplier_ Name
DATA: Supplier_ Address
DATA: Country
50
Scandinavian Clothing A/S
Kr. Augusts Gate 13
NO
109
Petterson AB
Blasieholmstorg 1
SE
316
Prime Sports Ltd
9 Carlisle Place
GB
. . .
. . . 3298
A Team Sports
. . . 2687 Julie Ann Ct
. . . US
data supplier_info; drop rc; length Supplier_Name $40 Supplier_Address $ 45 Country $ 2; if _N_=1 then do; declare hash S(dataset:'orion.supplier'); S.definekey('Supplier_ID'); S.definedata('Supplier_Name', 'Supplier_Address', 'Country'); S.definedone(); call missing(Supplier_Name, Supplier_Address, Country); end; set orion.product_list; rc=S.find(); if rc=0; run;
Partial PDV Supplier_ Name
Supplier_ Address
Country
Product _ID
Product_ Name
. Copy rig ht © SA S Institute Inc. A ll rig hts re se rve d.
Supplier _ID
.
...
D
rc
.
_N_ 1
Ausführung Auszug: HASH Table S KEY: Supplier _ID
DATA: Supplier_ Name
DATA: Supplier_ Address
DATA: Country
50
Scandinavian Clothing A/S
Kr. Augusts Gate 13
NO
109
Petterson AB
Blasieholmstorg 1
SE
316
Prime Sports Ltd
9 Carlisle Place
GB
. . .
. . . 3298
A Team Sports
. . . 2687 Julie Ann Ct
. . . US
Partial PDV Supplier_ Name
Supplier_ Address
Country
data supplier_info; drop rc; length Supplier_Name $40 Supplier_Address $ 45 Country $ 2; if _N_=1 then do; declare hash S(dataset:'orion.supplier'); S.definekey('Supplier_ID'); S.definedata('Supplier_Name', 'Supplier_Address', 'Country'); S.definedone(); call missing(Supplier_Name, Supplier_Address, Country); end; set orion.product_list; rc=S.find(); if rc=0; run; Product _ID 210000000000
Product_ Name
Children
Copy rig ht © SA S Institute Inc. A ll rig hts re se rve d.
Supplier _ID
... .
rc
D
-2147450842
-2147450842
_N_ 1
Ausführung Auszug: HASH Object S KEY: Supplier _ID
DATA: Supplier_ Name
DATA: Supplier_ Address
DATA: Country
50
Scandinavian Clothing A/S
Kr. Augusts Gate 13
NO
109
Petterson AB
Blasieholmstorg 1
SE
316
Prime Sports Ltd
9 Carlisle Place
GB
. . .
. . . 3298
. . .
A Team Sports
2687 Julie Ann Ct
. . . US
data supplier_info; drop rc; length Supplier_Name $40 Supplier_Address $ 45 Country $ 2; if _N_=1 then do; declare hash S(dataset:'orion.supplier'); S.definekey('Supplier_ID'); S.definedata('Supplier_Name', 'Supplier_Address', 'Country'); S.definedone(); call missing(Supplier_Name, Supplier_Address, Country); end; False set orion.product_list; rc=S.find(); if rc=0; run; -2147450842
Partial PDV Supplier_ Name
Supplier_ Address
Country
Product _ID 210000000000
Product_ Name
Children
Copy rig ht © SA S Institute Inc. A ll rig hts re se rve d.
Supplier _ID
.
...
D
rc -2147450842
_N_ 1
Ausführung Auszug: HASH Object S KEY: Supplier _ID
DATA: Supplier_ Name
DATA: Supplier_ Address
DATA: Country
50
Scandinavian Clothing A/S
Kr. Augusts Gate 13
NO
109
Petterson AB
Blasieholmstorg 1
SE
316
Prime Sports Ltd
9 Carlisle Place
GB
. . .
. . . 3298
. . .
A Team Sports
2687 Julie Ann Ct
. . . US
data supplier_info; drop rc; length Supplier_Name $40 Supplier_Address $ 45 Country $ 2; if _N_=1 then do; declare hash S(dataset:'orion.supplier'); S.definekey('Supplier_ID'); S.definedata('Supplier_Name', 'Supplier_Address', 'Country'); S.definedone(); call missing(Supplier_Name, Supplier_Address, Country); end; set orion.product_list; rc=S.find(); if rc=0; run;
Continue until _N_=6
Partial PDV Supplier_ Name
Supplier_ Address
Country
Product _ID
210200100009
Product_ Name Kids Sweat Round Neck,Large Logo
Copy rig ht © SA S Institute Inc. A ll rig hts re se rve d.
Supplier _ID
3298
...
D
rc .
_N_ 6
Ausführung Auszug: HASH Object S KEY: Supplier _ID
DATA: Supplier_ Name
DATA: Supplier_ Address
DATA: Country
50
Scandinavian Clothing A/S
Kr. Augusts Gate 13
NO
109
Petterson AB
Blasieholmstorg 1
SE
316
Prime Sports Ltd
9 Carlisle Place
GB
. . .
. . . 3298
A Team Sports
. . . 2687 Julie Ann Ct
. . . US
data supplier_info; drop rc; length Supplier_Name $40 Supplier_Address $ 45 Country $ 2; if _N_=1 then do; declare hash S(dataset:'orion.supplier'); S.definekey('Supplier_ID'); S.definedata('Supplier_Name', 'Supplier_Address', 'Country'); S.definedone(); call missing(Supplier_Name, Supplier_Address, Country); end; set orion.product_list; rc=S.find(); if rc=0; run;
Partial PDV Supplier_ Name
Supplier_ Address
Country
Product _ID
210200100009
Product_ Name Kids Sweat Round Neck,Large Logo
Copy rig ht © SA S Institute Inc. A ll rig hts re se rve d.
Supplier _ID
3298
...
D
rc 0
_N_ 6
Ausführung Auszug: HASH Object S KEY: Supplier _ID
DATA: Supplier_ Name
DATA: Supplier_ Address
DATA: Country
50
Scandinavian Clothing A/S
Kr. Augusts Gate 13
NO
109
Petterson AB
Blasieholmstorg 1
SE
316
Prime Sports Ltd
9 Carlisle Place
GB
. . .
. . . 3298
A Team Sports
. . . 2687 Julie Ann Ct
. . . US
data supplier_info; drop rc; length Supplier_Name $40 Supplier_Address $ 45 Country $ 2; if _N_=1 then do; declare hash S(dataset:'orion.supplier'); S.definekey('Supplier_ID'); S.definedata('Supplier_Name', 'Supplier_Address', 'Country'); S.definedone(); call missing(Supplier_Name, Supplier_Address, Country); end; set orion.product_list; rc=S.find(); if rc=0; run; Implicit OUTPUT;
True
Partial PDV Supplier_ Name A Team Sports
Supplier_ Address 2687 Julie Ann Ct
Country
US
Product _ID 210200100009
Product_ Name Kids Sweat Round Neck,Large Logo
Copy rig ht © SA S Institute Inc. A ll rig hts re se rve d.
Implicit RETURN; Supplier _ID
3298
...
D
rc
0
_N_
6
Die Find-Methode Die FIND Methode lokalisiert den Schlüsselwert im Hash Objekt und gibt die Datenwerte zurück. Allgemeine Form:
rc=object.FIND(); Der ReturnCode kann mit bedingter Logik verbunden werden, um verschiedene ReturnWerte abzufragen. Beispiel: Werte der ReturnCode Variablen Null (0) Nicht null
Übereinstimmung Keine Übereinstimmung
Copy rig ht © SA S Institute Inc. A ll rig hts re se rve d.
Length Anweisung data supplier_info; drop rc;
length Supplier_Name $40 Supplier_Address $ 45 Country $ 2;
if _N_=1 then do; declare hash S(dataset:'orion.supplier'); S.definekey('Supplier_ID'); S.definedata('Supplier_Name', 'Supplier_Address', 'Country'); S.definedone(); ..... end;
Partial PDV Supplier_ Name
Supplier_ Address
Count ry
Product _ID
.
Product_ Name
Supplie r _ID
. Copy rig ht © SA S Institute Inc. A ll rig hts re se rve d.
S.definedata: Die Datenkomponenten beziehen sich auf SAS Variablen und sollen als SAS Variablen auch angelegt werden , um automatisch befüllt werden zu können. Wie? Eine Möglichkeit: LENGTH nutzen Damit legt SAS in der Kompilierungsphase im Data Step diese als SAS Variablen im Zwischenspeicher PDV an.
CALL MISSING data supplier_info; drop rc; length Supplier_Name $40 Supplier_Address $ 45 Country $ 2; if _N_=1 then do; ... S.definedata('Supplier_Name', 'Supplier_Address', 'Country'); ...
Da die Datenelemente als SAS Variablen erstellt werden sollen mittels Length Anweisung - haben sie jedoch keinen Startwert (Initialisierungswert).
Sie kommen über das Hash Objekt, direkt in den PDV, nicht aus der Datei, und sie werden auch nicht zugewiesen call missing(Supplier_Name, Supplier_Address, mit Gleichzeichen = Country); Dies erzeugt folgende Meldung im Log: Call Missing: - Verhindert Note im Log NOTE: Variable Supplier_Name is uninitialized. - Weist Missingwerte als NOTE: Variable Supplier_Address is uninitialized. NOTE: Variable Country is uninitialized. Startwert zu Copy rig ht © SA S Institute Inc. A ll rig hts re se rve d.
Ergebnisse Partial PROC PRINT Output Product Information Obs
Product_ID
Supplier_ID
1 2 3 4 5 6 7 8 9 10
210200100009 210200100017 210200200022 210200200023 210200300006 210200300007 210200300052 210200400020 210200400070 210200500002
3298 3298 6153 6153 1303 1303 1303 1303 1303 772
Supplier_Name
Supplier_Address
A Team Sports A Team Sports Nautlius SportsWear Inc Nautlius SportsWear Inc Eclipse Inc Eclipse Inc Eclipse Inc Eclipse Inc Eclipse Inc AllSeasons Outdoor Clothing
2687 Julie Ann Ct 2687 Julie Ann Ct 56 Bagwell Ave 56 Bagwell Ave 1218 Carriole Ct 1218 Carriole Ct 1218 Carriole Ct 1218 Carriole Ct 1218 Carriole Ct 553 Cliffview Dr
Copy rig ht © SA S Institute Inc. A ll rig hts re se rve d.
Country US US US US US US US US US US
Ein weiteres Anwendungsbeispiel für Hash Objekte • •
Die Marketing Abteilung will jeweils die beiden Kunden mit dem höchsten und die beiden mit dem niedrigsten Umsatz herausfinden Ausgabe in 2 Dateien in EINEM Data Step Partial orion.orderfact Customer ID 63 5 45 41 183
ProductID 220101300017 230100500026 240600100080 240600100010 240200200039
Quantity 1 1 1 2 3
Total Retail Price $16.50 $247.50 $28.30 $32.00 $63.60
$$$
CostPrice PerUnit
Discoun t
$7.45 $109.55 $8.55 $6.50 $8.80
. . . . .
$ Copy rig ht © SA S Institute Inc. A ll rig hts re se rve d.
Hash Iterator Objekt (Hiter Objekt) Das Hash Iterator Objekt ist sehr gut geeignet zum effizienten Durchsuchen eines Hash Objekts. Dabei wird der Schlüssel genutzt, die Datei selbst muss nicht sortiert sein, das Hash Iterator Objekt sollte (aber muss nicht) sortiert sein. Auszug: Hash Object KEY: Total Retail Price 16.50 247.50 28.30 32.00 . . . 95.10 48.20 75.20 33.80
Auszug: Hiter View
KEY: Customer ID 63 5 45 41 . . . 10 10 89 5
KEY: Total Retail Price 1937.20 1796.00 1687.50 1561.80 . . . 3.20 3.00 2.70 2.60
KEY: Customer ID 70100 79 16 183 . . . 69 5 11171 79
Das Hash Iterator Objekt bezieht sich auf ein zuvor erstelltes Hash Objekt Copy rig ht © SA S Institute Inc. A ll rig hts re se rve d.
Anwendungsbeispiel: Syntax data top bottom; drop i; if _N_=1 then do; if 0 then set orion.orderfact(keep=CustomerID ProductID TotalRetailPrice); declare hash customer(dataset:'orion.orderfact', ordered:'descending'); customer.definekey('TotalRetailPrice', 'CustomerID'); customer.definedata('TotalRetailPrice', 'CustomerID', 'ProductID'); customer.definedone(); declare hiter C('customer'); end; C.first(); do i=1 to 2; output top; C.next(); end; Das Hiter Objekt bezieht sich C.last(); do i=1 to 2; auf ein zuvor erstelltes Hash output bottom; C.prev(); Objekt end; stop; run; Copy rig ht © SA S Institute Inc. A ll rig hts re se rve d.
Durchsuchen des Hash Objektes mit dem Hiter Objekt •
Vier Hiter Objekt Methoden geben die Werte basierend auf der Position im Hash Objekt zurück. FIRST
NEXT
LAST
PREV
Hash Object Key: A
Hiter Object View Data: B
Key: A
3 X
Data: B 3 X
1 Y
2 Z
2 Z
1 Y Copy rig ht © SA S Institute Inc. A ll rig hts re se rve d.
Ausführung Auszug: Hash Object customer KEY: Total Retail Price 16.50 247.50 28.30 32.00 . . . 95.10 48.20 75.20 33.80
KEY: Customer ID 63 5 45 41 . . . 10 10 89 5
DATA: Total Retail Price 16.50 247.50 28.30 32.00 . . . 95.10 48.20 75.20 33.80
DATA: Customer ID
DATA: Product ID
63 5 45 41
220101300017 230100500026 240600100080 240600100010 . . . 240500200016 240500200122 240700200018 220101400130
. . . 10 10 89 5
data top bottom; drop i; if _N_=1 then do; if 0 then set orion.orderfact (keep=CustomerID ProductID TotalRetailPrice); declare hash customer (dataset:'orion.orderfact', ordered:'descending'); customer.definekey('TotalRetailPrice', 'CustomerID'); customer.definedata('TotalRetailPrice', 'CustomerID','ProductID'); customer.definedone(); declare hiter C('customer'); end;
Beachten Sie: Das Hash Objekt selbst ist nicht sortiert!
PDV Customer ID
Product ID
.
Total RetailPrice
. Copy rig ht © SA S Institute Inc. A ll rig hts re se rve d.
D
.
i
D
.
_N_
1 ...
Ausführung Auszug: Hiter C View KEY: Total Retail Price 1937.20 1796.00 1687.50 1561.80 . . . 3.20 3.00 2.70 2.60
KEY: Customer ID 70100 79 16 183 . . . 69 5 11171 79
DATA: Total Retail Price 1937.20 1796.00 1687.50 1561.80 . . . 3.20 3.00 2.70 2.60
DATA: Customer ID
DATA: Product ID
70100 79 16 183 . . . 69 5 11171 79
240200100173 240200100076 230100700009 240300300090 . . . 230100500004 240100100433 240200100021 230100500045
data top bottom; drop i; if _N_=1 then do; if 0 then set orion.orderfact (keep=CustomerID ProductID TotalRetailPrice); declare hash customer (dataset:'orion.orderfact', ordered:'descending'); customer.definekey('TotalRetailPrice', 'CustomerID'); customer.definedata('TotalRetailPrice', 'CustomerID','ProductID'); customer.definedone(); declare hiter C('customer'); end;
Das Hiter Objekt jedoch ist absteigend sortiert, wie in der Syntax angegeben.
PDV Customer ID
Product ID
.
Total RetailPrice
. Copy rig ht © SA S Institute Inc. A ll rig hts re se rve d.
D
.
i
D
.
_N_
1 ...
Dateien erstellen mittels Hash Iterator Objekt Methoden data top bottom; drop i; if _N_=1 then do; if 0 then set orion.orderfact(keep=CustomerID ProductID TotalRetailPrice);
declare hash customer(dataset:'orion.orderfact', ordered:'descending');
customer.definekey('TotalRetailPrice', 'CustomerID'); customer.definedata('TotalRetailPrice', 'CustomerID', 'ProductID'); customer.definedone();
declare hiter C('customer');
end;
C.first(); do i=1 to 2; output top; C.next(); end; C.last(); do i=1 to 2; output bottom; C.prev(); end; stop; run; Copy rig ht © SA S Institute Inc. A ll rig hts re se rve d.
PROC PRINT Ausgabe proc print data=top; title 'Top 2 Big Spenders'; run; proc print data=bottom; title 'Bottom 2 Frugal Spenders'; run;
Top 2 Big Spenders
Obs 1 2
CustomerID
ProductID
TotalRetail Price
70100 79
240200100173 240200100076
$1,937.20 $1,796.00
Bottom 2 Frugal Spenders
Obs 1 2
CustomerID
ProductID
TotalRetail Price
79 11171
230100500045 24 240200100021
$2.60 $2.70
Copy rig ht © SA S Institute Inc. A ll rig hts re se rve d.
Vielen Dank für Ihre Teilnahme SAS® Live Web Classes 2017: Termine und Anmeldung •
https://support.sas.com/edu/locations.html?locationId=LW&ctry=DE
Copy rig ht © SA S Institute Inc. A ll rig hts re se rve d.
Weitere Informationen und Kurse zu diesem Thema… SAS® Programmierung 3: Effiziente Techniken des Datenmanagements 03. – 05. April 2017, Heidelberg 19. – 21. Juni 2017, Heidelberg
Copy rig ht © SA S Institute Inc. A ll rig hts re se rve d.
Nächstes Webinar@Lunchtime: 27. April 2017 SAS und das Hadoop-Ökosystem Bastian Weiß, Kybeidos
Copy rig ht © SA S Institute Inc. A ll rig hts re se rve d.
Folien zum Download unter www.sas.de/lunchtime WIE HAT IHNEN UNSER WEBINAR GEFALLEN?
sas.com
Copy rig ht © SA S Institute Inc. A ll rig hts re se rve d.