Dateien und Datenfiles
Wir zeigen Dir, wie's geht!
Daten aus Dateien laden
Um Daten verarbeiten zu können, ist es notwendig sie erst einmal zu laden. Du kannst Daten laden, indem Du Datenfiles in das Kommandofenster ziehst oder indem Du das Kommando load verwendest. Als Datenfiles gelten alle Dateien, die üblicherweise Daten in tabellarischer Form enthalten:
Textdateien: *.dat, *.csv, *.txt, *.labx, *.jdx
Binäre Dateien: *.ndat, *.xls, *.xlsx, *.ods, *.ibw
Hinweis: im Allgemeinen sollten die Unterschiede in den deutschen und den englischen Zahlenformaten kein Problem für NumeRe darstellen. Sollte es jedoch trotzdem vorkommen, dass ein Zahlenformat falsch interpretiert wurde, ersetze alle Kommas durch Punkte und versuche es erneut. Sollte das immer noch nicht klappen, lese unten bei den generischen Textdateien weiter.
Wir starten mit einem Beispiel, dass Du so direkt bei Dir ins Kommandofenster eingeben kannst:
<- load "<scriptpath>/examples/amplitude.dat"
-> Daten aus "[...]/scripts/examples/amplitude.dat" wurden erfolgreich in den Speicher geladen: der Datensatz besteht aus 11
Zeile(n) und 4 Spalte(n).
-> ans = {1, 11, 1, 4}
<- data(#,:)
-> ans = {"omega", "b=3", "b=5", "b=0"}
Mit diesem Kommando wurden die Daten aus der Datei "scripts/examples/amplitude.dat" in die Tabelle data() geladen. Diese Tabelle ist das Standardziel, wenn Daten geladen werden sollen. Mit der Option -totable[=TABLE()] kann die Zieltabelle jedoch auch noch angepasst werden. Hierbei würde -totable (ohne explizit angegebene Tabelle) eine neue Tabelle aus dem Dateinamen generieren; in unserem Fall also amplitude().
Das Token <scriptpath> ist ein Platzhalter, der den Scripte-Ordner von NumeRe enthält. Davon gibt es noch einige weitere:
<loadpath> für den Standardladepfad (Der "Datenfiles"-Ordner in der Baumansicht)
<savepath> für den Standardspeicherpfad (Der "Gespeicherte Dateien"-Ordner in der Baumansicht)
<plotpath> für den Standardspeicherpfad für erzeugte Plots (wenn sie als Bilder gespeichert werden)
<procpath> für die Prozedurenbibliothek
<wp> für einen schnell wechselbaren Arbeitspfad (Kann mit dem Kommando workpath PFAD geändert werden)
<> für das NumeRe-Stammverzeichnis (hier ist z.B. numere.exe zu finden)
<this> für das aktuelle Verzeichnis der aktuell ausgeführten Code-Einheit (Im Kommandofenster identisch zu <>, bei Scripten und Prozeduren identisch zu deren Verzeichnis)
Du kannst Dir jetzt die Daten noch weiter ansehen, indem Du z.B. das Kommando show data() verwendest. Das wird standardmäßig die Tabelle in einem neuen Fenster in einer tabellarischen Ansicht anzeigen, wie Du sie von den geläufigen Tabellenkalkulationen kennst. Probiere auch gerne, einzelne Zeilen oder Spalten aus dem Datensatz zu extrahieren.
Du kannst die Daten in der Tabelle nun auch als Plot darstellen lassen. Verwende dazu wieder das Kommando plot, wobei Du die x- und y-Spalten angeben musst:
<- plot data(:, 1:2)
Du wirst erkennen, dass die angezeigte Legende aus den beiden Spaltenüberschriften generiert wurde. Aber auch hier kannst Du eine eigene Legende angeben, wenn Du direkt auf den Datensatz folgend die Legende als Zeichenkette angibst. Willst Du hingegen keine Legende haben, gibst du einfach eine leere Zeichenkette für sie an (plot data(:, 1:2) "").
Außerdem wird Dir auffallen, dass NumeRe hier automatisch auf einzelne Punkte für den Plot (Scatter-Plot) umgeschaltet hat. Da in Tabellen meist Daten enthalten sind, verwendet NumeRe diese Darstellung, um auch in einem Plot den Unterschied zu verdeutlichen. Willst Du stattdessen die Punkte verbunden haben, kannst Du die Option connect (oder interpolate bei vielen Datenpunkten) verwenden.
Du kannst auch mehrere Datenreihen (und auch Funktionen) in den gleichen Plot zeichnen, indem Du diese durch Komma getrennt angibst (Eigene Legenden wären jeweils vor dem Komma anzugeben):
<- plot data(:, 1:2), data(:, 1:3), data(:, 1:4)
Hieran erkennst Du, dass jeder neue Plot automatisch eine neue Farbe und (im Falle von Datenreihen) ein eigenes Symbol verwendet. Die Zahl an Farben und Symbolen ist begrenzt und nach 20 Plots wiederholen sich die Farb-Symbol-Kombinationen. Es ist natürlich möglich, die Farben über die Option plotcolors=COLORS anzupassen, falls die Standardfarben sich für den aktuellen Plot nicht eignen.
Daten in Dateien speichern
Um Daten zu speichern stehen Dir zwei Kommandos zur Verfügung: save und export. Das Kommando save wird standardmäßig Daten in das NumeRe-eigene Binärdatenformat NDAT speichern, um Metadaten und Präzision zu erhalten. Das Kommando export wird standardmäßig Textdateien erzeugen, um die Daten so einer breiteren Empfängerschaft verfügbar zu machen. Du kannst beide Kommandos ausprobieren:
<- save data()
-> Daten wurden erfolgreich nach "[...]/save/data_2022-05-31_093748.ndat" gespeichert.
<- export data()
-> Daten wurden erfolgreich nach "[...]/save/data_2022-05-31_093755.dat" gespeichert.
Wie Du siehst, werden die Dateien im <savepath> unter einem automatisch genierten Dateinamen, der das aktuelle Datum enthält, gespeichert. Du kannst aber auch eigene Dateinamen angeben:
<- save data() -file="my_amplitude"
-> Daten wurden erfolgreich nach "[...]/save/my_amplitude.ndat" gespeichert.
<- export data() -file="my_exported_amplitude"
-> Daten wurden erfolgreich nach "[...]/save/my_exported_amplitude.dat" gespeichert.
Hierbei könntest Du natürlich auch einen anderen Pfad oder ein anderes Dateiformat angeben. Die einzigen Bedingungen sind, dass der Pfad auch existiert und NumeRe das Dateiformat kennt:
<- export data() -file="<loadpath>/my_exported_amplitude.csv"
-> Daten wurden erfolgreich nach "[...]/data/my_exported_amplitude.csv" gespeichert.
Zuletzt kannst Du natürlich auch den Bereich der Tabelle einschränken, der gespeichert werden soll, z.B.
<- export data(:,1:2) -file="my_extraction.txt"
-> Daten wurden erfolgreich nach "[...]/save/my_extraction.txt" gespeichert.
Generische Textdateien lesen
Leider haben Textdateien die unangenehme Eigenschaft, dass sie in beliebigen Formaten auftreten können. Da ist es ziemlich wahrscheinlich, dass NumeRe die ein oder andere Textdatei nur fehlerhaft oder gar nicht interpretieren kann. Um dieses Problem zu lösen, kannst Du mit dem Kommando read Textdateien auch als unformatierte Zeichenketten einlesen. Den Rückgabewert dieses Kommandos kannst Du direkt in ein Cluster speichern:
<- htmlFile{} = read "<scriptpath>/examples/htmlfile.html";
<- num(htmlFile{})
-> ans = 1266
<- htmlFile{1}
-> ans = "<area shape="poly" coords="903,90,893,90,892,130,902,130" title=31,3725 />"
Hierbei haben wir das Semikolon zum Unterdrücken der Antwort eingeführt. Anderenfalls hätte NumeRe die 1266 Zeilen HTML (eigentlich handelt es sich nur um eine Ansammlung von <area /> tags) auf der Kommandozeile ausgegeben. Mit der Funktion num() haben wir die Zahl der Elemente in dem Cluster gelesen.
Mit diversen Zeichenkettenfunktionen kann man nun versuchen, den Inhalt der Datei in etwas Interpretierbares zu übersetzen. So können wir den Inhalt des title Attributes z.B. mittels strfnd() finden und dann über das folgende Leerzeichen den Wert des Attributes lesen. Das ist allerdings mühsam:
<- substr(htmlFile{}, strfnd("title=", htmlFile{})+6, strrfnd(" ", htmlFile{})-strfnd("title=", htmlFile{})-6)
-> ans = {"31,3725", "5,8824", "19,7183", "27,1318", "2,2556", ...}
Einfacher geht's da mit der textparse() Funktion. Hier übernimmt ein Pattern das Suchen in dem String und extrahiert das gewünschte Element. Hierbei wird mit den Extraktoren %s eine Zeichenkette, %f ein numerischer Wert und %a ein arbiträrer Wert, der ignoriert werden soll, bezeichnet. Wichtig ist nur, dass die Begrenzungen der jeweiligen Extraktoren eindeutig sind.
<- textparse(htmlFile{}, "<area shape=\"poly\" coords=\"%a\" title=%s />")
-> ans = {"31,3725", "5,8824", "19,7183", "27,1318", "2,2556", ...}
Dir wird sicher aufgefallen sein, dass in beiden Fällen die Operation automatisch vektorisiert wurde. Tatsächlich ist htmlFile{} eine Abkürzung für htmlFile{:}, so dass hiermit automatisch über alle Indices in htmlFile{} iteriert wird. Ebenso ist data() eine Abkürzung für data(:, :).
Die Funktion textparse() kann mittels %f die ausgelesenen Werte auch gleich in numerische Werte umwandeln (trotz des deutschen Nummernformates), so dass damit weitergearbeitet werden kann:
<- textparse(htmlFile{}, "<area shape=\"poly\" coords=\"%a\" title=%f />")
-> ans = {31.3725, 5.8824, 19.7183, 27.1318, 2.2556, ...}
Textdateien schreiben
Natürlich kannst Du Deine Zeichenketten auch in eine Datei schreiben. Dazu verwendest Du das Kommando write, dem Du die Zeichenketten und den Zieldateinamen übergibst. Außerdem musst Du noch ein paar Optionen beachten:
<- write htmlFile{} -set file="<savepath>/my_text_file.txt" mode=trunc nq
Dabei wird der Inhalt des htmlFile{} Clusters zeilenweise in die Datei my_text_file.txt im Standardspeicherpfad geschrieben. Mit dem Modus mode=trunc sagst Du aus, dass Du eine eventuell bereits vorhandene Datei überschreiben willst. Mit mode=app würdest Du neue Inhalte einfach ans Ende anfügen (hilfreich z.B. bei Logfiles). Die Option nq ist aus historischen Gründen nötig und definiert, dass die umschließenden Anführungszeichen der Zeichenketten nicht in die Datei geschrieben werden sollen.
Du kannst write auch ohne Cluster verwenden, indem Du die einzelnen Zeilen kommagetrennt oder explicit umgebrochen übergibst:
<- write "Erste Zeile", "Zweite Zeile" -set file="<savepath>/my_four_line_file.txt" mode=trunc nq
<- write "Dritte Zeile\nVierte Zeile" -set file="<savepath>/my_four_line_file.txt" mode=app nq
Mit dem letzten Beispiel haben wir dann auch bereits die Funktionsweise der mode=app Option veranschaulicht. Der Inhalt der Datei my_four_line_file.txt wird dann folgendermaßen aussehen:
Erste Zeile
Zweite Zeile
Dritte Zeile
Vierte Zeile