Eine Zuweisung mehrmals ausführen ohne eine Schleife zu benutzen

Wie rufe ich R-Funktionen auf, wie selektiere ich Daten, ich weiß nicht genau ....

Moderatoren: EDi, jogo

jogo
Beiträge: 2086
Registriert: Fr Okt 07, 2016 8:25 am

Re: Eine Zuweisung mehrmals ausführen ohne eine Schleife zu benutzen

Beitrag von jogo »

Hallo Bill,
Bill hat geschrieben: Fr Apr 24, 2020 11:43 pm Nur der Neugierde halber, was meinst du mit Teufelszeug im Rahmen der fehlenden Anwendungsmöglichkeiten von Rekursionen innerhalb der apply-Funktionen-Familie ? :P
Bei dem Teufelszeug im Zusammenhang mit Funktionen geht es um globale Zuweisungen.
Die Unfähigkeit der apply-Funktionen zur Rekursion ist ein anderes Thema.

Gruß, Jörg
bigben
Beiträge: 2780
Registriert: Mi Okt 12, 2016 9:09 am

Re: Eine Zuweisung mehrmals ausführen ohne eine Schleife zu benutzen

Beitrag von bigben »

Hallo Bill,
Bill hat geschrieben: Fr Apr 24, 2020 11:43 pmAlso die Ausführung der 10000000 Zuweisungen im Rahmen der for Schleife dauerten bei mir in etwa eine knappe Dreiviertelsekunde, also doch ziemlich gering schätze ich.
Das ist eine valide Schätzung, aber mit Blick auf die Messungenauigkeit die aus Deiner Reaktionsgeschwindigkeit und der Ansprechungenauigkeit eines Touchscreens folgt, eine mit erheblicher Unsicherheit versehene. Einigen wir uns: Wenn Du das hundert Mal hintereinander machen müsstest, könntest Du in der Zeit einen Kaffee holen gehen, würdest ihn aber nicht mehr austrinken.
Richtig ist aber auch, dass man in R neben klassischer Statistik auch sehr gut Monte Carlo-Statistiken und Simulationen rechnen kann und dank der Zauberkraft der Kombinatorik ist man dann schnell bei großen Zahlen. Auch ich habe schon so manches Mal vor meinem Rechner gesessen und mir gewünscht, er wäre schneller Ich will also nicht das Streben nach schnellen Implementierungen grundsätzlich herabwürdigen. Im Grundsatz ist schneller besser. Ich glaube nur, dass diesem Aspekt in der online-Diskussion zuviel Gewicht begemessen wird, verglichen mit der tatsächlichen Bedeutung für die meisten User.

Grundsätzlich gehört zu einer Sprache neben dem Wortschatz und der Grammatik eben auch deren üblicher Gebrauch und in R vermeidet der die for- und die while-Schleife zugunsten anderer Formen von "Vielfachem durchlaufen lassen".

LG,
Bernhard
---
Programmiere stets so, dass die Maxime Deines Programmierstils Grundlage allgemeiner Gesetzgebung sein könnte
Benutzeravatar
EDi
Beiträge: 1599
Registriert: Sa Okt 08, 2016 3:39 pm

Re: Eine Zuweisung mehrmals ausführen ohne eine Schleife zu benutzen

Beitrag von EDi »

R ist eben eine Sprache die sowohl prozedural (wie z.B. C++) als auch funktional (wie z.B. Haskell) geschrieben werden kann.

Beides ist in R ähnlich gut und hängt vermutlich von persönlichen Vorlieben ab. Ich mag es eher Funktional, auch weil ich das besser debuggen kann bzw. lesbarer und verständlicher empfinde.

Und wenn's _wirklich_ auf die Zeit ankommt, kann man a) parallelisieren (z.B. parallel package), b) in C++ auslagern (Rcpp package), c) woanders rechnen (cloud) oder d) Hirnschmalz nutzen und optimiert programmieren.

Oft ist auch gar nicht die Zeit das Problem, sondern der Speicher. Da helfen dann c) und d).
Bitte immer ein reproduzierbares Minimalbeispiel angeben. Meinungen gehören mir und geben nicht die meines Brötchengebers wieder.

Dieser Beitrag ist lizensiert unter einer CC BY 4.0 Lizenz
Bild.
Benutzeravatar
EDi
Beiträge: 1599
Registriert: Sa Okt 08, 2016 3:39 pm

Re: Eine Zuweisung mehrmals ausführen ohne eine Schleife zu benutzen

Beitrag von EDi »

Dadurch, dass ich viel funktional schreibe, kann ich auch fast immer ziemlich billig parallelisieren und so Zeit sparen.

Nehme da meist das furrr package und kann damit mit gleichem Code lokal parallelisieren oder in der Cloud/Cluster rechnen. Sehr angenehm (vor allem auch gut mit dplyr zusammenzubringen)...
Bitte immer ein reproduzierbares Minimalbeispiel angeben. Meinungen gehören mir und geben nicht die meines Brötchengebers wieder.

Dieser Beitrag ist lizensiert unter einer CC BY 4.0 Lizenz
Bild.
Hufeisen
Beiträge: 162
Registriert: Fr Aug 31, 2018 6:34 pm

Re: Eine Zuweisung mehrmals ausführen ohne eine Schleife zu benutzen

Beitrag von Hufeisen »

Könnt ihr ein Beispiel für funktional und prozedural nennen?
bigben
Beiträge: 2780
Registriert: Mi Okt 12, 2016 9:09 am

Re: Eine Zuweisung mehrmals ausführen ohne eine Schleife zu benutzen

Beitrag von bigben »

Hallo Hufeisen,

prozedurale Programmierung, funktionale Programmierung und objektiorientierte Programmierung sind drei verschiedene Programmierparadigmen, man kann statt Paradigma vielleicht auch Grundhaltungen oder Gedankensysteme sagen. Eine exakte Definition und genaue Abgrenzung sind dabei nicht immer möglich. Typische Vertreter prozeduraler Programmiersprachen sind Assembler und C, typische Vertreter funktionaler Programmiersprachen sind LISP, Haskell und Erlang und typische Vertreter objektiorientierten Programmierens sind SmallTalk und Java. Früher waren prozedurale am nächsten am Metall und haben daher auf ressourcenschwachen Rechnern brilliert, dann wurden die Rechner immer leistungsstärker und die Programme immer größer und dann dominierten die objektorientierten Sprachen und jetzt, mit dem Trend zu vielen Kernen, besinnt man sich wieder mehr auf die funktionalen.

Dabei entstehen Mischsprachen, die einen Mischmasch aus allem umfassen. R ist ein gutes Beispiel, wo man einer ursprünglich prozedural und begrenzt auch funktionalen Sprache später drei verschiedene Objektsysteme aufgepresst hat und alles irgendwie durcheinander verwendet.

Beim prozeduralen Programmieren erklärt man dem Computer die Prozedur:

Code: Alles auswählen

i <- 1
while(i<10){
  print("Hallo")
  i <- i + 1
}
ich sage, dass er mit i eine Laufzeitvariable bereithalten soll, welches Kriterium dem Abbruch dient. Ich definiere, ob die Laufzeitvariable von 0 bis 9 oder von 1 bis 10 läuft, obwohl das für das Ergebnis gar keinen Unterschied mach. Ich muss dabei sehr aufpassen, ob ich jetzt wirklich zehn oder neu oder elfmal was printe aber dafür ist das leicht in Maschinencode zu übersetzen.

Die funktionale Variante wäre

Code: Alles auswählen

a <- replicate(10, print("Hallo"))
Im Idealfall sage ich dem Computer, was er machen soll und nicht, wie er es machen soll. Ob es eine Laufzeitvarialbe gibt und von wo nach wo die läuft, das passiert alles im Hintergrund. Das macht alles eine Funktion. Ich kann einer Funktion eine Funktion als Argument übergeben. Im Idealfall nimmt eine Funktion Daten als Argument an und gibt sie als Rückgabewert zurück. print gibt etwas auf den Bildschirm aus und verändert damit etwas jenseits seines Rückgabewerts. Bei Funktional-Hartlinern wird das schon als wesentliches Problem angesehen. Wenn ich nämlich den o. g. Code in 50 Threads parallel laufen lasse ist nicht definiert, in welcher Reihenfolge etwas ausgegeben wird, weil man ja nicht weiß, welcher Thread schneller und welcher langsamer läuft. In strengen funktionalen Sprachen wie Haskell ist i <- i + 1 unmöglich, weil eine Variable ihren einmal festgelegten Wert nicht ändern kann. Deshalb gibt es auch keine Schleifen mit Laufvariablen und man muss alles, was man in anderen Sprachen mit Schleifen macht mit echter Rekursion machen.

Objektorientiert wäre so etwas in der Art wie

Code: Alles auswählen

"Hallo".printTimes(10)
Das Objekt "Hallo" bringt seine eigenen Methoden mit, so was ähnliches wie Funktionen, die man auf dieses Objekt anwenden kann. Hier etwa eine Methode, die etwas 10 Mal ausgibt. Die Methode gehört zur Klasse und ein Objekt gehört immer mindestens einer Klasse an. Man kann sich vorstellen, dass bei einem riesigen Softwareprojekt ein Programmierer allein die Klasse "String" beschreibt. Er muss dafür sorgen, dass die printTimes-Methode funktioniert, alle anderen müssen nur wissen, dass "Hallo" eine Instanz der String-Klasse ist und dass die String-Klasse ein printTimes-Methode hat. Sie müssen sich darum keine Gedanken machen, deshalb können auch sehr umfangreiche Programme in großen Teams erstellt werden, weil die Veränderung in einer Klasse allen anderen egal sein kann, solange die Schnittstelle / Methoden definiert bleiben.

Das alles hat immer Vor- und Nachteile und deshalb kann man sich da herzlich die Köpfe einschlagen oder sich eklestizistisch immer das heraussuchen, was man will.

Wenn EDi so funktionell programmiert, dass er alles parallelisieren kann, dann darf in seinen Funktionen eben auch kein print vorkommen. Man erkauft oft das eine durch das andere.
Wie gesagt, ist die Grenzziehung nur für Hardliner exakt. Sprachen, die alles können (R, Scala, neueste Java-Version) sind sehr mächtig, werden dafür aber auch sehr komplex. In LISP kannst Du nicht "1 + 1" schreiben, weil der Name der Funktion immer vorne steht, also "(+ 1 1)". Klingt lästig, aber dabei kann es nie zu Fragen kommen, ob jetzt Punkt- oder Strichrechnung zuerst geht. Der typische R-Fehler "1:n+1" kann überhaupt nicht vorkommen und man ist stolz, dass die vollständige Syntax der Sprache auf eine Tafel passt und in 10 Minuten vollständig erklärt werden kann. Es hat halt immer alles zwei Seiten.

LG,
Bernhard
---
Programmiere stets so, dass die Maxime Deines Programmierstils Grundlage allgemeiner Gesetzgebung sein könnte
Bill
Beiträge: 35
Registriert: Fr Mär 06, 2020 8:04 pm

Re: Eine Zuweisung mehrmals ausführen ohne eine Schleife zu benutzen

Beitrag von Bill »

Hallo EDi,
Hallo Bernhard,

EDi du schriebst,
Dadurch, dass ich viel funktional schreibe, kann ich auch fast immer ziemlich billig parallelisieren und so Zeit sparen.
Wäre das denn nicht so wenn du prozedural programmieren würdest? Warum ist das parallelisieren billiger (und Zeit sparender) wenn du funktional programmierst?

Bernhard du meintest:
Dabei entstehen Mischsprachen, die einen Mischmasch aus allem umfassen. R ist ein gutes Beispiel, wo man einer ursprünglich prozedural und begrenzt auch funktionalen Sprache später drei verschiedene Objektsysteme aufgepresst hat und alles irgendwie durcheinander verwendet.
Gibt es auch Nachteile daraus? Also das R eben neben dem ursprünglich prozeduralen und begrenzt funktionalen auch das objektorientierte Paradigma aufgedrückt wurde?
Ich finde deine Beispiele sehr interessant. Das Beispiel zur Deutlichmachung der objektorientierten Variante finde ich recht ungewöhnlich.
Programmieren (einige) Leute in R echt so?

Liebe Grüße

Bill
bigben
Beiträge: 2780
Registriert: Mi Okt 12, 2016 9:09 am

Re: Eine Zuweisung mehrmals ausführen ohne eine Schleife zu benutzen

Beitrag von bigben »

Hallo Bill,
Bill hat geschrieben: So Apr 26, 2020 9:36 pm
Dadurch, dass ich viel funktional schreibe, kann ich auch fast immer ziemlich billig parallelisieren und so Zeit sparen.
Wäre das denn nicht so wenn du prozedural programmieren würdest? Warum ist das parallelisieren billiger (und Zeit sparender) wenn du funktional programmierst?
Das wird aus meinem Beispiel nicht so deutlich, aber einige Grundgedanken der funktionalen Programmierung, z. B. dass Funktionen sich wie mathematische Funktionen verhalten sollten (verwerten die Argumente, geben vorhersagbare Werte vorhersagbaren Typs zurück und haben keine "Nebenwirkungen") passen sehr gut zum Parallelisieren. Weil EDi sie von vorneherein beachtet, muss er seinen Code nicht groß umschreiben, wenn er ihn statt auf einem Kern seiner CPU auf 20 Kernen bei Amazon laufen lassen will. Nicht umschreiben müssen == billiger.
Bernhard du meintest:
Dabei entstehen Mischsprachen, die einen Mischmasch aus allem umfassen. R ist ein gutes Beispiel, wo man einer ursprünglich prozedural und begrenzt auch funktionalen Sprache später drei verschiedene Objektsysteme aufgepresst hat und alles irgendwie durcheinander verwendet.
Gibt es auch Nachteile daraus? Also das R eben neben dem ursprünglich prozeduralen und begrenzt funktionalen auch das objektorientierte Paradigma aufgedrückt wurde?
Schwer zu sagen. Wenn Du über die Vorteile echt objektorientierter Programmierung liest, dann geht es eben um die Vorteile beim Erstellen großer Programme. Aber wer macht sowas in R? Die meisten von uns wollen doch nur ihre Daten auswerten und dafür braucht man eigentlich nie viele tausende Zeilen Code. Insofern finde ich es schwierig bis uninteressant, R nach solchen Kriterien zu beurteilen. Encapsulation und Inheritance sind heilige Grale der Objektorientierung. Ich müsste nachlesen um Dir zu sagen, ob es sowas im S3-Objektsystem überhaupt gibt. In echt objektorientierten Sprachen ist es halt echt wichtig, welche Methoden Dein Objekt von welcher Eltern-Großeltern-Urgroßeltern-Klasse geerbt hat.

Ich finde deine Beispiele sehr interessant. Das Beispiel zur Deutlichmachung der objektorientierten Variante finde ich recht ungewöhnlich.
Programmieren (einige) Leute in R echt so?
Das war wohl unzureichend beschrieben: Nein, in R kann man so nicht programmieren. In R ist das keine gültige Syntax. "Normale" Objektorientierung kann so aussehen. In R sieht ein Methodenaufruf so aus wie ein Funktionsaufruf und ohne nachzulesen weiß ich ehrlich gesagt nicht mal, ob es einen großen Unterschied gibt. In Java könnte man die Zahl 1 ausgeben mit

Code: Alles auswählen

java.lang.System.out.println(1)
println ist eine Methode, die etwas in den Printstream ausgibt, der sie implementiert. Dafür brauchen wir den PrintStream, der die normale Standardkonsole bedient. Der findet sich im Feld "out" der Klasse "System", in dem man alternativ auch den PrintStream "err" für Fehlermeldungen hätte finden können, der dann, weil er von der gleichen Klasse PrintStream erbt auch die Methode "println" gehabt hätte. Beide PrintStreams finden wir in der Klasse "System", die etwas besonderes ist, weil man von dieser Klasse keine weiteren Objekte instantiieren kann. System wiederum erbt von der der Klasse java.lang.Object die wiederum die Wurzel der Klassenhierarchie ist. Noch Fragen? Du kannst viele, viele Jahre regelmäßig R Objekte nutzen, ohne Dir jemals über so etwas Gedanken machen zu müssen. Ich weiß das, weil ich das lebe. In Java machst Du ohne das nix. Nichtmal ne Zahl ausgeben.
Wenn Du in R eine lineare Regression durchführst erhälst Du ein Objekt zurück, dessen Benutzung sich für mich anfühlt wie ein Record-Datentyp mit generischen Funktionen in einer funktionalen Sprache. Der Informatiker wird erschaudern und mir die theoretischen Unterschiede vorhalten - in meinem Alltag mit R regt mich höchstens auf, dass es nicht das eine, sondern zwei, Objektsysteme gibt (und noch ein Drittes, über das ich seit Jahren immer schon mal was lesen wollte, das ich bisher aber nie brauchte). Man muss also wissen, dass man an die Information fast immer über das Dollarzeichen $, manchmal aber nur über den Klammeraffen @ kommt. Es gibt aufregendere Themen.

LG,
Bernhard
---
Programmiere stets so, dass die Maxime Deines Programmierstils Grundlage allgemeiner Gesetzgebung sein könnte
Hufeisen
Beiträge: 162
Registriert: Fr Aug 31, 2018 6:34 pm

Re: Eine Zuweisung mehrmals ausführen ohne eine Schleife zu benutzen

Beitrag von Hufeisen »

Danke für die tollen Antworten. Ich hatte schon mal versucht, mir das auf Wikipedia zu erschließen. Aber wirklich eingängig war für mich nicht. Danke sehr, so ist es sehr verständlich!
Bill
Beiträge: 35
Registriert: Fr Mär 06, 2020 8:04 pm

Re: Eine Zuweisung mehrmals ausführen ohne eine Schleife zu benutzen

Beitrag von Bill »

Hallo Bernhard,

da kann ich mich Hufeisen nur anschließen, tolle Antworten!

Auch dass die Programmiersprache R von euch "Erfahrenen" hier wirklich auch als sehr mächtig eingeschätzt wird, motiviert mich umso mehr, mehr über jene zu lernen.

Liebe Grüße

Bill
Antworten