Menu

Vektoren in R: c(), seq(), Indexierung und vektorisierte Rechnung

Vektoren sind die Grundeinheit von R - selbst eine einzelne Zahl ist einer. Wie du sie mit c() erzeugst, indizierst (ab 1!), mit logischen Masken filterst und Rechnungen auf ganzen Vektoren auf einmal ausführst.

Diese Seite enthält ausführbare Editoren - bearbeiten, ausführen und Ausgabe sofort sehen.

In R ist alles ein Vektor

Die meisten Sprachen haben Skalare - Einzelwerte - und dann irgendeinen Containertyp, um mehrere davon zu halten. R überspringt den Skalar. Ein Vektor ist eine geordnete Sammlung von Werten, die alle einen Typ teilen, und er ist die Einheit, auf der alles andere aufbaut. Selbst was wie eine einsame Zahl aussieht, ist ein Vektor der Länge 1:

c() - kurz für combine - ist der Weg, einen Vektor von Hand zu bauen. length() sagt dir, wie viele Elemente er enthält. Und 5 allein meldet is.vector als TRUE mit Länge 1: R hört nie auf, mit Vektoren zu arbeiten, es arbeitet nur manchmal mit sehr kurzen.

Dieses Design ist der Grund, warum R-Code anders aussieht als Python oder JavaScript: Operationen, für die du anderswo eine Schleife schreiben würdest, gelten hier für ganze Vektoren in einem Ausdruck. Dazu kommen wir weiter unten.

Eine Regel, die du dir jetzt einprägen solltest: Alle Elemente eines Vektors haben denselben Typ. Übergibst du c() eine Mischung, beschwert es sich nicht - es konvertiert stillschweigend alles in den flexibelsten vorhandenen Typ:

Eine Zeichenkette in der Mischung macht alles zu Zeichenketten ("1", "TRUE"). Logicals unter Zahlen werden zu 1 und 0. Diese Coercion folgt einer festen Rangordnung - logical → integer → double → character - und passiert ohne Warnung, weshalb ein verirrtes "7" in einer Zahlenspalte deinen ganzen Datensatz still in Text verwandeln kann. Die vollständige Hierarchie wird unter Datentypen behandelt; wenn du wirklich gemischte Werte halten musst, sind dafür Listen da.

Sequenzen erzeugen: :, seq() und rep()

Jedes Element in c() zu tippen wird schnell mühsam. R hat drei Abkürzungen für regelmäßige Muster:

  • 1:10 ist der Alltagsfall: ganze Zahlen von einer Grenze zur anderen in Schritten von 1.
  • seq() verallgemeinert das: Wähle die Schrittweite mit by = oder sag mit length.out =, wie viele Elemente du willst, und lass R die Abstände berechnen.
  • seq_len(n) erzeugt 1 bis n und ist der sichere Weg, Schleifenindizes zu bauen - anders als 1:n liefert es korrekt einen leeren Vektor, wenn n gleich 0 ist, statt rückwärts 1 0 zu zählen.
  • rep() wiederholt: times = wiederholt den ganzen Vektor am Stück (1 2 1 2 1 2), each = wiederholt jedes Element an Ort und Stelle (1 1 1 2 2 2). Die beiden sind leicht zu verwechseln; führ den Ausschnitt aus und vergleiche.

Indexierung: R zählt ab 1

Eckige Klammern holen Elemente heraus. Das erste Element ist [1] - nicht [0]. Kommst du von Python oder JavaScript, ist das der mit Abstand häufigste frühe Stolperstein:

Drei Dinge lohnen hier eine Pause:

  • Du kannst mit einem Vektor von Positionen indizieren - fruits[c(2, 4)] greift das zweite und vierte in einem Zug.
  • Negative Indizes bedeuten "alles außer". fruits[-1] ist der Vektor ohne sein erstes Element. Das ist völlig anders als in Python, wo -1 das letzte Element meint. Positive und negative Indizes lassen sich nicht im selben Aufruf mischen.
  • fruits[0] ist kein Fehler - es gibt ein leeres character(0) zurück. Ein Off-by-One-Bug erzeugt in R oft still leere Ergebnisse statt eines Absturzes, deshalb lohnt sich ein Blick auf length(), wenn etwas weiter hinten rätselhaft leer aussieht.

Elemente können außerdem Namen tragen, was dir eine dritte Art der Indexierung gibt - über Etiketten:

Benannte Vektoren funktionieren wie eine leichtgewichtige Nachschlagetabelle und halten Code lesbar: prices["tea"] sagt, was es bedeutet, prices[2] nicht.

Logische Masken und which()

Der mächtigste Weg zu indizieren führt über einen logischen Vektor - eine Maske aus TRUE/FALSE-Werten in der Länge der Daten. Jeder Vergleich auf einem Vektor erzeugt genau das:

temps > 24 gibt nicht eine Antwort - es gibt fünf, eine pro Element. Steckt diese Maske in [ ], bleiben die Elemente erhalten, an denen die Maske TRUE ist. Bedingungen kombinierst du mit & (und) und | (oder), behandelt beim Rest der Operatoren.

which() übersetzt eine Maske in Positionen: hier 2 3 5, die Indizes der heißen Messwerte. Greif dazu, wenn du wissen musst, wo die Treffer sind - um sie zu melden oder um einen anderen Vektor an denselben Stellen zu indizieren. Zum bloßen Filtern ist temps[temps > 24] direkter als temps[which(temps > 24)].

Dieses Filter-mit-Maske-Muster ist das Rückgrat praktisch aller Datenarbeit in R - es kommt direkt zurück, wenn du Zeilen eines Data Frames filterst.

Vektorisierte Rechnung und die Recycling-Regel

Arithmetik gilt in R elementweise über ganze Vektoren - keine Schleife nötig:

Die erste Zeile ist das Kernmerkmal: prices * 2 verdoppelt jedes Element. Wo andere Sprachen eine for-Schleife brauchen, braucht R einen Operator - und die vektorisierte Form ist zugleich kürzer und schneller, weil das Schleifen darunter in optimiertem C passiert. Schreib eine for-Schleife, wenn jeder Schritt vom vorherigen abhängt; für elementweise Rechnung vektorisiere.

Die dritte Zeile zeigt die Recycling-Regel: Haben die Vektoren unterschiedliche Längen, wiederholt R den kürzeren, bis es passt. c(10, 20) wird zu 10 20 10 20 recycelt und ergibt 11 22 13 24. Das Recyceln von 2 über einen Vektor der Länge 3 ist genau das, was prices * 2 funktionieren ließ - ein Skalar ist einfach ein Vektor der Länge 1, der recycelt wird.

Recycling ist sauber, wenn die längere Länge ein exaktes Vielfaches der kürzeren ist. Wenn nicht, berechnet R trotzdem ein Ergebnis - und meldet eine Warnung:

Du bekommst 11 22 13 plus eine Warnung, dass die Länge des längeren Objekts kein Vielfaches der Länge des kürzeren ist. Behandle diese Warnung als Fehlermeldung: Teilweises Recycling ist fast nie das, was du meintest, und bedeutet meist, dass zwei Vektoren, die gleich lang sein sollten, es nicht sind.

Sortieren, Umkehren, Duplikate entfernen

Drei kleine Hilfsmittel, die du ständig nutzen wirst:

sort() ordnet die Werte, rev() dreht die bestehende Reihenfolge ohne zu sortieren um, und unique() entfernt Duplikate und behält das erste Auftreten. Keines davon verändert x - wie fast alles in R geben sie einen neuen Vektor zurück und lassen das Original in Ruhe.

Was du mitnimmst

  • Ein Vektor ist R's Grundeinheit: geordnet, durchgehend ein Typ, und selbst Einzelwerte sind Vektoren der Länge 1.
  • Bauen mit c(), Muster erzeugen mit :, seq() und rep() - und denk daran, dass c() gemischte Typen still konvertiert.
  • Indexierung beginnt bei 1; negative Indizes entfernen Elemente; Namen erlauben Indexierung über Etiketten.
  • Logische Masken (x[x > 5]) sind das Filter-Idiom der ganzen Sprache; which() macht aus einer Maske Positionen.
  • Rechnung ist vektorisiert, kürzere Vektoren werden recycelt, und eine Teil-Recycling-Warnung bedeutet, dass du einen Bug hast.

Als Nächstes: Listen - der Container für den Fall, dass deine Werte nicht alle einen Typ teilen.

Häufig gestellte Fragen

Wie erzeugt man einen Vektor in R?

Mit der Funktion c() (kurz für combine): x <- c(10, 20, 30). Für regelmäßige Sequenzen nutzt du 1:10, seq(0, 1, by = 0.25) oder rep(0, 5). Alle Elemente müssen am Ende denselben Typ haben - mischst du Typen, konvertiert R stillschweigend alle in den flexibelsten.

Beginnt die Indexierung in R bei 0 oder bei 1?

Bei 1. x[1] ist das erste Element, x[length(x)] das letzte. Das lässt jeden stolpern, der von Python, JavaScript oder C kommt - es gibt kein Element x[0] (die Abfrage liefert einen leeren Vektor, keinen Fehler, was den Bug leise macht).

Was macht die Recycling-Regel in R?

Rechnest du mit zwei Vektoren unterschiedlicher Länge, wiederholt R den kürzeren, bis er zum längeren passt. c(1, 2, 3, 4) + c(10, 20) ergibt 11 22 13 24. Ist die längere Länge kein Vielfaches der kürzeren, berechnet R trotzdem ein Ergebnis, meldet aber eine Warnung - behandle diese Warnung als Bug.

Was macht which() in R?

Es wandelt einen logischen Vektor in die Positionen seiner TRUE-Werte um. Ergibt x > 5 den Vektor FALSE TRUE TRUE, dann ergibt which(x > 5) den Vektor 2 3. Nutze es, wenn du die Positionen selbst brauchst; zum bloßen Filtern ist die direkte Indexierung mit dem logischen Vektor (x[x > 5]) einfacher.

Coddy programming languages illustration

Lerne mit Coddy zu programmieren

LOS GEHT'S