2017-05-15 1 views
0

Problem: Ich habe eine .tip-Datei von NASDAQ, die ich parsen muss. Offizieller Name: GENIUM CONSOLIDATED FEED
Die Datei ist eine CSV-ähnliche Datei mit Semikolon und Newline für neue Einträge unterschiedlicher Struktur und somit keine konstante Kopfzeile. Aber es hat eine entsprechende xsd-Schemadatei, die den Inhalt und die Struktur beschreiben sollte, aber ich kann keinen klaren Weg sehen, von der Datei zu einem Strukturergebnis zu gelangen. Wurden mit einer Liste Setup versucht, wo message einen Namen Analysieren einer NASDAQ-.tip-Datei

in einer Liste wird
x <- scan("cran_tasks/NOMX_Comm_Close2.tip", what="", sep="\n") 
y <- strsplit(x, ';') 
names(y) <- sapply(y, `[[`, 1) 
y <- sapply(y, `[`, -1, simplify = FALSE) 
y <- sapply(y, as.list) 

Die Datei wie folgt strukturiert:

messageType;key1Value;key2Value;...;..;/n 
messageType;key1Value;key2Value;.....;/n  

BDSr;i2;NAmGITS; 
BDx;i106;Si18;s2;SYmNC;NAmNASDAQ OMX Commodities;CNyNO;MIcNORX; 
BDm;i672;Si018171;s2;Ex106;NAmFuel Oil;SYmNCFO;TOTa+0200;LDa20141011; 
BDIs;i10142;SiNP;s2;ISsNP;NAmNord Pool ASA; 
m;i122745;t191500.001;Dt20170509;ISOcY;ISOtY; 
m;i122745;t192808.721;Dt20170509;ISOcN;ISOtY;SEp275.45; 
Oi;i122745;t054425.600;OPi2840; 

ich eine funktionierende SQL-Code gehabt haben setzen Sie die Datei zu analysieren, aber es Es hat sich gezeigt, dass der Fall so spezifisch ist, dass er auch gegen geringfügige Änderungen in der Struktur robust ist, wie die Reihenfolge der verschiedenen keyValue-Paare. Ich suche nach einer Möglichkeit, die Struktur der Information auszunutzen, um eine robuste und wartbare Lösung, vorzugsweise in R, erstellen zu können. Ich habe mit einigen regulären Ausdrücken versucht, aber trotzdem habe ich eine Menge kontextspezifischer Ich hoffe, dass die Strukturierung mit einer Tabelle oder einem Datenrahmen, die die Schlüsselinformationen enthält, zu einer nachhaltigen Lösung führen kann.

Alle Hinweise oder Vorschläge sind mehr als willkommen.

Link auf die XML/XSD Datei und die html sheet Angabe Schlüssel und ein .tip file

TIP Message Format Das TIP-Protokoll ist ein getaggt Textprotokoll. Eine TIP-Nachricht ist eine Folge von Tag- und Wertpaaren, die durch Semikolon getrennt sind. Ein Tag ist null oder mehr Großbuchstaben, gefolgt von einem Kleinbuchstaben. Auf das Tag folgt unmittelbar der Wert. Beispiele für Tags sind "FLd", "STa". Das erste Tag in einer Nachricht ist immer der Nachrichtentyp. Das Nachrichtentyp-Tag hat keinen Wert. Ein Beispiel eines Nachrichtentyp-Tags ist "BDSh". IP-Nachrichten werden mit UTF-8 codiert, sofern nicht anders angegeben. Die maximale Länge einer TIP-Nachricht ist , angegeben mit der Konstante MAX_MESSAGE_LENGTH (2048 Byte). Jede maximale Feldlänge schließt alle Escapezeichen '\' aus. Es werden keine leeren Werte gesendet; Ausnahmen sind Nachrichtentyp-Tags und boolesche Tags (die Anwesenheit des Tags selbst entspricht einem 'wahren' Wert). Für ein Dezimalfeld (d. H. Den Datentyp Float) wird die Länge als X, Y angegeben, wobei X die maximale Anzahl der Ziffern im ganzzahligen Teil des Felds (links vom Trennzeichen) ist. Y ist die Anzahl der Dezimalstellen (rechts neben dem Trennzeichen ). Die Reihenfolge der disseminierten Tags ist nicht festgelegt, d. H. Der Client darf keine Annahmen über die Reihenfolge der Tags treffen. Die einzige feste Komponente einer Nachricht ist der Nachrichtentyp, der immer zuerst in den Nachrichtendaten platziert wird. Beachten Sie, dass neue Nachrichten und Felder in zukünftigen Versionen des Protokolls hinzugefügt werden können. Um die Kompatibilität mit zu gewährleisten, sollten Clients nicht erkannte Nachrichtentypen und Feldtags ignorieren.

+0

Ich weiß, dass diese Frage mindestens zwei downvotes recived, kann ich verstehen, warum, aber bitte geben sie dann an, was ich verbessern kann. Es gibt einige implizite Programmierfragen, aber mein Problem ist, dass ich nicht in der Lage war, ein Design/eine Strategie zu entwickeln, die robust waren. Und indem Sie spezifische Fragen stellen; Wie "Wie man eine CSV nach xsd-Spezifikationen in xml umwandelt", werde ich implizit eine bestimmte Strategie wählen, um das Problem anzugehen. – Thorvall

Antwort

1

Die folgende Lösung data.table analysiert die angegebene .tip-Datei und gibt eine data.table mit Tag- und Wertpaaren zurück. Dies ist wahrscheinlich ein guter Ausgangspunkt, um die relevanten Daten weiter zu extrahieren.

library(data.table) 

# read downloaded file from local disk 
tip_wide <- fread(
    "NOMX_Comm_Close2.tip" 
    , sep = "\n" 
    , header = FALSE 
) 

# split tip messages into tag and value pairs 
# thereby rehaping from wide to long format 
# and adding a row number 
tip_long <- tip_wide[, unlist(strsplit(V1, ";")), 
        by = .(rn = seq_len(nrow(tip_wide)))] 

# get message type tag as the first entry of each message 
msg_type <- tip_long[, .(msg.type = first(V1)), by = rn] 
# make message type a separate column for each tag-value-pair using join 
# remove unnecessary rows 
tip_result <- msg_type[long, on = "rn"][msg.type != V1] 

# split tag and value pairs 
tip_result[, c("tag", "value") := 
      data.table(stringr::str_split_fixed(V1, "(?<=^[A-Z]{0,9}[a-z])", 2))] 

tip_result 
#   rn msg.type  V1 tag value 
#  1:  1  BDSr  i2 i  2 
#  2:  1  BDSr NAmGITS NAm GITS 
#  3:  2  BDx  i106 i  106 
#  4:  2  BDx  Si18 Si  18 
#  5:  2  BDx  s2 s  2 
# ---          
#905132: 95622  BDCl  s2 s  2 
#905133: 95622  BDCl i2368992 i 2368992 
#905134: 95622  BDCl Il2368596 Il 2368596 
#905135: 95622  BDCl  Op1 Op  1 
#905136: 95622  BDCl  Ra1 Ra  1 

beachte, dass die value Spalte vom Typ Zeichen ist.

Der reguläre Ausdruck"(?<=^[A-Z]{0,9}[a-z])" verwendet eine Blick hinter Behauptung (siehe ?"stringi-search-regex") die geteilten Muster zu definieren. Beachten Sie, dass {0,9} verwendet wird hier statt * als der Blick hinter Muster darf nicht unbegrenzt sein (kein * oder + Operatoren.)

+0

Danke. Hat mein Problem gelöst. Vor allem die "by" -Klausel in der Funktion [], die für mich neu ist Ich bin immer noch ein wenig puzzled von Ihnen reqex: ? <=^[AZ] {0,9} [az] – Thorvall

+0

Die 'by = 'ist' data.table' Syntax und funktioniert nicht mit einfachen Datenrahmen. – Uwe

+0

Die Regex hat mich auch überrascht ;-). Es ist ein Blick hinter dem sich danach spalten lässt. – Uwe

Verwandte Themen