Kann NumeRe Excel?

Fragt man in seinem Umfeld nach einem Programm, mit dem man Daten auswerten kann, wird mit sehr hoher Wahrscheinlichkeit mindestens einmal Microsoft Excel als eine mögliche Lösung genannt. Das ist, abhängig vom konkreten Anwendungsfall, sicher eine valide Wahl. Abseits der einfachsten Fälle stellt sich jedoch die Frage, ob Excel wirklich für alle Fälle geeignet ist und ob es nicht vielleicht sinnvoller ist, direkt mit NumeRe zu arbeiten.

Doch kann NumeRe, was auch Excel kann?

In diesem Artikel werden wir ein typisches Beispiel in Excel und NumeRe aufbereiten und die verschiedenen Schritte gegenüberstellen. Dabei werden wir keine allzu komplexen Operationen verwenden. Excel-Profis, die einen Blick auf NumeRe werfen wollen, sind hier aber vielleicht gerade deswegen richtig. Zwar werden wir Teile des Codes im Text aufgreifen, die komplette Lösung findet sich aber auch unten im Anschluss.

Dieser Artikel ist inspiriert von einem Blogbeitrag bei Appsilon: https://www.appsilon.com/post/excel-functions-in-r

Erzeugen eines Datensatzes

Excel

Daten in Excel zu bekommen ist ein No-Brainer. Man kann sie einfach direkt in die Zellen eines neuen Tabellenblattes tippen und - wenn man sich bemüht - formatiert man sie noch als eine Tabelle, wie rechts einmal dargestellt ist. Das haben wir alle bestimmt schon hunderte Male so gemacht, daher werden wir hier auch nicht weiter darauf eingehen. Wobei, nebenbei bemerkt, die Formatierung als Tabelle signifikante Vorteile bringt und demzufolge möglichst immer gemacht werden sollte.

NumeRe

NumeRe dagegen ist etwas restriktiver, wie die Tabellen aufgebaut sind. Werte in den Zellen einzelner Spalten müssen jeweils den gleichen Datentyp aufweisen. Um die Tabelle zu erzeugen, kann man new xlstable() verwenden. In diese schreibt man dann die Werte spaltenweise durch xlstable(:, 1) = {1:5} für beispielsweise die ID, wie im Folgenden auch nochmals im Detail dargestellt ist. Alternativ ist es natürlich auch möglich, die Daten zeilenweise hineinzuschreiben.

xlstable(#, :) = {"ID", "First Name", "Last Name", "Age", "Department", "Salary", "Date Joined"};

xlstable(:, "ID") = {1:5};

xlstable(:, "First Name") = {"John", "Jane", "Mark", "Bob", "Susan"};

xlstable(:, "Last Name") = {"Doe", "Dean", "Markson", "Barston", "Cup"};

xlstable(:, "Age") = {31, 33, 27, 41, 39};

xlstable(:, "Department") = {"IT", "Sales", "Marketing", "IT", "IT"};

xlstable(:, "Salary") = {5000, 4500, 5000, 6500, 7000};

xlstable(:, "Date Joined") = to_time("", {"2018-05-27", "2020-08-14", "2021-07-13", "2015-01-10", "2012-09-04"});

xlstable().convert(7, "datetime");

Eine vielleicht zentrale Beobachtung, die man hierbei machen kann, ist, dass in den Zellen einer NumeRe-Tabelle keine Ausdrücke sondern nur Werte gespeichert werden können. Das steht im Gegensatz zum Vorgehen, wie man es aus Excel kennt. Sobald das verstanden ist, so hat man den fundamentalen Unterschied zwischen NumeRe und Excel bereits erfolgreich überwunden.

Alternativ kann man auch die eventuell vorhandene Excel-Datei direkt laden (Achtung, dafür darf diese nicht zugleich in Excel geöffnet sein). Abgesehen von XLSX-Dateien werden hierbei natürlich auch noch weitere Dateiformate wie *.csv, *.txt, *.jdx, *.ods oder *.ndat von Haus aus unterstützt:

load "data.xlsx" -totable=xlstable()

Natürlich kann man auch die Tabelle direkt manuell bearbeiten bzw. Daten hineinkopieren. Das erreicht man, indem man das Kommando edit auf die Tabelle anwendet:

edit xlstable()

Das Ergebnis schließlich sieht - abgesehen von zusätzlichen Anführungszeichen - nahezu ähnlich zum Ergebnis in Excel aus. Um dieses zu sehen, kann man entweder show xlstable() eintippen oder doppelt auf den entsprechenden Eintrag im Variablenviewer (befindet sich unten rechts im Fenster) klicken.

Datenverarbeitung - Formeln und Ausdrücke

Einfache Statistiken

Wir beginnen mit einem einfachen Anwendungsfall: einfache Statisiken der Salary-Spalte. Wir möchten einmal die Bandbreite der monatlichen Gehälter erheben, sowie den Mittelwert, Standardabweichung und den Median desselben berechnen.

Es macht natürlich keinen Sinn, eine Standardabweichung von 5 Werten zu berechnen, trotzdem führen wir das hier aus Gründen der Anschauung einmal durch.

Excel

Das geht in Excel schnell mittels der folgenden Funktionen (die je nach eingestellter Sprache unterschiedlich lauten können und anhand derer Argumente man direkt den Vorteil einer Formatierung als Tabelle sehen kann):

=MIN(Table1[Salary])

=AVERAGE(Table1[Salary])

=MEDIAN(Table1[Salary])

=MAX(Table1[Salary])

=STDEV(Table1[Salary])

NumeRe

In NumeRe können wir die Statistiken einer Tabelle oder Spalte ganz einfach mit dem Keyword stats erhalten:

stats xlstable(:, "Salary")

Alternativ gibt es natürlich für alle zentralen Statistikwerte auch dedizierte Funktionen wie z.B. min(xlstable(:, "Salary")), die dann ebenfalls in eine nette Tabellendarstellung umgewandelt werden können.

Beide Lösungen sind rechts einmal direkt aufeinanderfolgend dargestellt. Damit wird ersichtlich, dass stats sich vor allem für einen schnellen Einblick über die Daten eignet und gezielte Statistiken eher mit den dedizierten Funktionen berechnet werden.

Verknüpfen von Zeichenketten

Verknüpfen von Zeichenketten kommt relativ häufig in Datenauswertungen vor, daher schauen wir uns einmal an, wie das konkret am einfachen Beispiel des Zusammensetzens der Mitarbeiternamen aus Vor- und Nachnamen umgesetzt wird.

Excel

In Excel verwendet man dazu entweder eine Funktion wie CONCAT() oder direkt den &-Operator. Innerhalb der Tabelle sieht die entsprechende Formel dann wie folgt aus:

=[@[First Name]] & " " & [@[Last Name]]

Das Ergebnis ist unten dargestellt.

NumeRe

NumeRe verwendet zum Verketten von Zeichenketten den +-Operator, ansonsten unterscheidet sich die Syntax tatsächlich kaum: 

xlstable(:, "Full Name") = xlstable(:, "First Name") + " " + xlstable(:, "Last Name")

Bedingungen und logische Ausdrücke

Logische Bedingungen auf die Daten anzuwenden ist in vielen Fällen wichtig, um Abhängigkeiten und Zusammenhänge sichtbar zu machen. Wir wollen einmal bestimmen, welche der Mitarbeiter in der Tabelle ein höheres Gehalt als das monatliche Durchschnittsgehalt erhalten. 

Excel

In Excel verwendet man dazu die IF()-Funktion wie folgt:

=IF([@Salary] > AVERAGE([Salary]), "Y", "N")

Das Ergebnis ist wieder unten dargestellt. Wenn man sich stattdessen mit logischen Werten zufrieden gibt, kann man auch einfach nur direkt =[@Salary] > AVERAGE([Salary]) verwenden.

NumeRe

NumeRe kann logische Ausdrücke ebenfalls direkt auswerten, die Zielspalte muss jedoch händisch konvertiert werden.

xlstable(:, "Higher than avg. Salary") = xlstable(:, "Salary") > avg(xlstable(:, "Salary"));

xlstable().convert(ncols, "logical");

Um ein komplett identisches Ergebnis wie in Excel zu erhalten, kann man auch den komplexeren Ternary-Operator ? :  verwenden:

xlstable(:, "Higher than avg. Salary") = xlstable(:, "Salary") > avg(xlstable(:, "Salary")) ? "Y" : "N";

Zeichenkettenverarbeitung

Als Beispiel für eine sehr einfache Verarbeitung von Zeichenketten wollen wir noch die Initialien der Mitarbeiter aus deren Vor- und Nachnamen bestimmen. 

Excel

Dazu benötigen wir in Excel die LEFT()-Funktion, deren Ergebnis wir wieder verknüpfen:

=LEFT([@[First Name]],1) & LEFT([@[Last Name]],1)

Damit erhält man das folgende Ergebnis:

NumeRe

NumeRe kann direkt auf das erste Zeichen eines Strings mittels firstch() zugreifen:

xlstable(:, "Initials") = firstch(xlstable(:, "First Name")) + firstch(xlstable(:, "Last Name"));

Falls man stattdessen die Initialen aus den kompletten Namen bestimmen möchte, kann man z.B. die folgende Zeile verwenden, die allerdings etwas komplex aussehen mag:

xlstable(:, "Initials") = firstch(textparse(xlstable(:, "Full Name"), "%s %a")) + firstch(textparse(xlstable(:, "Full Name"), "%a %s"));

Datumsoperationen

Neben den Zeichenketten-Operationen sind Datumsoperationen mit die häufigsten Datenoperationen, die gleichzeitig auch am meisten Kopfzerbrechen bereiten können. Wir wollen hier jedoch eher einen einfachen Fall betrachten und so Feinheiten wie Zeitzonen und Sommerzeit einmal beiseite lassen.

Excel

Um final zu bestimmen, wie viel Jahre Erfahrung unsere Mitarbeiter inzwischen angesammelt haben, verwenden wir die YEAR() und TODAY()-Funktionen in Excel (Beachte, dass das Ergebnis anders aussehen kann, wenn du den Code bei dir ausführst):

=YEAR(TODAY()) - YEAR([@[Date Joined]])

NumeRe

NumeRe arbeitet bei Datumsangaben stets auf Sekunden-Basis (in UTC+0, um genau zu sein). Das ist zu berücksichtigen, wenn wir mit time() arbeiten. Als unmittelbaren Vorteil erhalten wir mit der folgende Methode anteilige Jahre als Ergebnis, die wir zusätzlich auf eine Nachkommastelle runden:

xlstable(:, "Years exp.") = round((time() - xlstable(:, "Date Joined")) / (24*3600*365), 1);

Datenaggregation und Visualisierung

Als letzten Schritt für diesen Artikel betrachten wir einmal die Möglichkeit, Daten auf Basis von logischen Ausdrücken zu aggregieren und daraus einen einfachen Barchart zu generieren. Die Datenaggregation ist dabei sehr einfach gehalten; wir wollen lediglich erheben, wie sich die monatlichen Gehälter auf die einzelnen Abteilungen verteilen.

Excel

Um das in Excel zu machen, verwenden wir hier die SUMIF()-Funktion. Um die Funktion noch kopierbar zu machen, beziehen wir uns für den Vergleichswert auf die Zelle links neben des Ausdrucks. Damit ergibt sich als Formel

=SUMIF(Table1[Department], H9, Table1[Salary])

Aus diesem Ergebnis ein Barchart zu erstellen, erfordert dann wiederum nur wenige Klicks.

NumeRe

In NumeRe erfordert dieselbe Aufgabe etwas mehr Aufwand, bietet damit aber auch mehr Kontrolle über den tatsächlichen Prozess. Zunächst erstellen wir uns mit new department_salaries() eine neue Tabelle. Um diese zu befüllen, verwenden wir die Tabellemethode TAB().indexof(), um uns die Indices zu unseren Vergleichswerten zu bestimmen, mit denen wir dann direkt mittels sum() summieren können. Zusätzlich betten wir die gesamte Logik noch in eine for-Schleife ein, die über die Liste an eindeutigen Abteilungen iteriert, um das Ganze noch skalierbar zu halten.

for (sDepartment -> strunique(xlstable(:, "Department")))

idx{} = xlstable().indexof(5, sDepartment);

department_salaries(nrows+1, :) = {sDepartment, sum(xlstable(idx{}, "Salary"))};

endfor -mask

Allerdings ist anzumerken, dass die eigentliche Operation, um die Informationen für die IT als ein einzelnes Department zusammen zu stellen, auch in einer einzelnen Zeile formuliert werden kann. Damit ist der Schreib-Mehraufwand im Vergleich zu Excel eher unbedeutend.

sum(xlstable(xlstable().indexof(5, "IT"), "Salary"))

Um das Ergebnis dann anschließend als ein Barchart darzustellen, ist gerade mal eine einzige weitere Zeile Code nötig, wobei hier die Option bars entscheidend ist. Ohne diese würde man statt des Barcharts einen gewöhnlichen Scatter-Plot erhalten.

plot department_salaries(:, 2) -set xticklabels=department_salaries(:, 1) box bars [:, 0:20'k] ylabel="Salary" xlabel="Department" font=heros

Fazit: Ist NumeRe eine gute Alternative zu Excel und sollte man umsteigen?

Um es kurz zu machen: wenngleich man sicher fast alle typischen Excel-Aufgaben problemlos mit NumeRe erledigen kann, ist ein kompletter Umstieg in die NumeRe-Welt und gleichzeitiger Verzicht auf eine weitere Spreadsheet-Applikation in keinem Szenario wirklich sinnvoll. NumeRe erweitert den Funktionsumfang von Excel signifikent und mag noch viele  weitere Vorteile haben, die wir in einem zukünftigen Artikel beleuchten werden, war jedoch nie als ein kompletter Excel-Ersatz geplant, insbesondere nicht für den allgegenwärtigen Gelegenheits-Excel-Nutzer, der es gewohnt ist, viel mit der Maus zu arbeiten.

Sucht man jedoch Möglichkeiten, komplexere Probleme zu lösen oder gar ganze Datenauswertungen zu automatisieren, kann ein Einstieg trotzdem sinnvoll sein, da insbesondere in der Kombination beider Welten ein großes Potential liegt. Excel-Power-User wären genau die richtigen Kandidaten dafür.

Bereit zum Nachmachen? Hier ist der Code: