Ich bin vor kurzem umgezogen und wurde von meiner alten Hausverwaltung gebeten, die Wände und die Decken der verlassenen Wohnung zu streichen. Ich habe mich sogleich im Internet um Vergleichsangebote von Malerbetrieben bemüht. Dort sollte ich gleich zu Beginn die zu streichende Fläche in Quadratmetern angeben ... mmh, ich hätte natürlich sofort die Grundfläche und die Anzahl Räume angeben können und gehofft, dass die Betriebe eine einfache Hochrechnung für die Angebotserstellung verwenden. Aber direkt die zu streichende Fläche zu ermitteln, schien mir etwas komplexer als eine Schätzung aus dem Stegreif.
Lösung mit R
Früher hätte ich das Problem in einer Excel-Mappe gelöst, aber diesmal wollte ich R als Taschenrechner einsetzen.
Angabe der Grundmaße
Zunächst habe ich ein paar Eckdaten als Variablen definiert:
zimmerhöhe<-2.8
anzahl_türen<-6
anzahl_fenster<-5
Dann habe ich die Grundfläche der Räume angegeben. Für das Berechnen der Deckenfläche kann ich natürlich die bekannten Quadratmeter des Bodens verwenden, aber für die Wände muss ich für jeden Raum Länge und Breite mit der Deckenhöhe verrechnen. Da ich also Länge und Breite einmal multiplikativ und einmal additiv kombiniere, habe ich mich dafür entschieden, alle Raummaße zunächst als Vektoren zu speichern.
grundflächen_räume<-list(kueche=c(3.4,3.7),
arbeitszimmer=c(3.0,5.0),
wohnzimmer=c(3.0,5.0),
bad=c(1.5,1.8),
flur=c(1.1,2.5),
wc=c(0.8,2.8),
schlafzimmer=c(3.0,5.0))
Von der später zu errechnenden Gesamtfläche muss ich natürlich noch Türen und Fenster abziehen. Die Türen nehme ich doppelt für beide Seiten und ziehe eine Seite für die Haustüre ab. Die Flächenberechnung erfolgt über die prod()-Funktion, die mir das Produkt der Elemente eines Vektors, hier die Maße in Metern, berechnet.
türenfläche<-prod(c(2.10,1.06))*(anzahl_türen*2-1)
fensterfläche<-prod(c(1.6,1.0))*anzahl_fenster
Damit es nicht zu einfach wird, muss ich für das Bad und für das WC noch Wände mit Fliesen unterschiedlicher Höhe abziehen. Dafür nehme ich wieder Länge und Breite der Räume und multipliziere sie mit der gemessenen Fliesenhöhe. Natürlich möchte ich die Maße der Räume nicht zweimal angeben und redundant vorhalten, daher hole ich mir die Vektoren aus der Raumauflistung von weiter oben.
fließen_wc<-sum(2*grundflächen_räume$wc) * 1.3
fließen_bad<-sum(2*grundflächen_räume$bad)* 2.0
Zuletzt fehlt noch die Küchenzeile, die sich vereinfacht nur über eine Wand erstreckt
kuechzeile<-3.4*2.4
Benutzerdefinierte Funktion für Wandflächen
Nun zur Wandfläche insgesamt. Ich habe die Berechnung in eine Funktion gekapselt.
f_wandfläche<-function(grundflächen){
prod(grundflächen)+sum(2*grundflächen)*zimmerhöhe;
}
Best Practice: Vektorisierung statt Schleifen
Da ich mich über die Jahre mit mehreren Programmiersprachen intensiver auseinandergesetzt habe, vor allem mit Python, war ich zunächst versucht, die Berechnung aller Räume über eine Schleife zu lösen. Diese würde alle Räume ablaufen und auf jedes Element die Funktion anwenden. Etwas wie Folgendes:
wandfläche_gesamt = 0
for(raum in grundflächen_räume){
wandfläche_gesamt = wandfläche_gesamt + f_wandfläche(raum)
}
Es funktioniert zwar wunderbar, ist aber gerade in R die falsche Vorgehensweise. Der Hintergrund dazu ist, dass die Schleife schrittweise Wiederholungen durchführt. Es ist deutlich performanter, die Berechnung in R vektorisiert durchzuführen. Bei unserer Handvoll Räume ist das völlig egal. Bei größeren Datensätzen mit tausenden von Zeilen wird es dann schon spürbarer. Die folgende Zeile verwendet die sapply-Funktion, die eine Funktion auf einen Vektor in einem Rutsch anwendet und das Ergebnis wieder als Vektor zurückmeldet.
wandflächen<-sapply(grundflächen_räume,f_wandfläche)
#Hier das Ergebnis
#kueche arbeitszimmer wohnzimmer bad flur wc schlafzimmer
#52.34 59.80 59.80 21.18 22.91 22.40 59.80
Ergebnis
Die Maße der alten Wohnung hatte ich leider nicht genau vorliegen und musste einiges schätzen. Als finaler Check sollte die Fläche aber der tatsächlichen Fläche von etwa 65 m² entsprechen. Daher berechnete ich die Gesamtfläche aus den Angaben wieder mit der sapply-Funktion und wendete auf den Vektor die prod-Funktion an, um das Produkt aus Länge und Breite zu ermitteln.
grundfläche_gesamt<-sum(sapply(grundflächen_räume,prod))
#Das Ergebnis:
#65.27
Für meine finale Wandfläche muss ich nun nur noch meinen Vektor der Einzelflächen aufaddieren und die Spezialflächen, wie Fenster und Türen, abziehen.
wandfläche_gesamt<-sum(wandflächen)-türenfläche-fensterfläche-fließen_wc-kuechzeile-fließen_bad
So, das Ergebnis lautet etwa 235 m².
PS: Ich hatte mittlerweile einen Vor-Ort-Termin mit einem Malermeister. Er hat die Wohnung grob vermessen und hat über eine Faustregel 220 m² ermittelt. Auch nicht schlecht!