Will man einen leeren Vektor eines bestimmten Typs erzeugen, geht das mit der Funktion vector. Insbesondere bei FOR-Schleifen empfielt es sich, vorher einen Vektor der passenden Länge zu erzeugen und nicht in jedem Schleifendurchgang den Vektor zu verlängern, da das sehr ineffizient ist.
v1 <- vector(mode="character", length=10) v2 <- vector(mode="integer", length=5) v3 <- vector(mode="numeric", length=3) v4 <- vector(mode="logical", length=8)
Allerdings sind die so erzeugten Vektoren nicht wirklich leer, sondern zum Beispiel bei numeric und integer mit Nullen aufgefüllt.Wollen wir einen Vektor mit NAs erzeugen, dann können wir das einfach mit dem Wiederholungsbefehl rep erreichen. Dieser ist aber erstmal vom Typ logical. In den meisten Fällen ist das nicht so schlimm, denn sobald ein Wert hineingeschrieben wird, ändert sich der Typ entsprechend. Jetzt gibt es aber noch den (seltenen) Fall, dass wir von Anfang an den richtigen Typ brauchen. Dazu nimmt man einfach den NA-Vektor und konvertiert in mit as.numeric oder as.character oder as.XXX in den gewünschten Typ.
a <- rep(NA, 10) class(a) b <- as.character(rep(NA, 5)) class(b)
Beim Aneinanderhängen von data.frames mit rbind wird der Typ automatisch konvertiert.
df1 <- data.frame(x = 1:6, y = rnorm(6), z = c("rot","grün")) df2 <- data.frame(x = 7:9, y = NA, z = NA) class(df2$y) df3 <- rbind(df1, df2) class(df3$y) class(df3$z)
Und hier der Einsatz in einer Schleife
# Das hier ist kein gutes Beispiel für eine Schleife, da es einfach ohne Schleife mit 1:10 %% 2 gelöst werden kann x <- rep(NA, 10) for (i in 1:10) { x[i] <- i %% 2 }
Und hier noch ein kleines Benchmark-Ergebnis, das den Geschwindigkeitsvorteil zeigt. Übrigens ist auch hier die Schleife unnötig und deutlich langsamer als die vektoriellen Befehle (23x so langsam). Es lohnt sich also fast immer, eine Schleife zu vermeiden.
library(rbenchmark) n = 50000 benchmark(x_verlaengern = { x = NA for (i in 1:n) { if(i%%2==0) { x[i] <- 2*x[i-1] } else { x[i] <- rnorm(1) } } }, feste_laenge = { x <- rep(NA, n) for (i in 1:n) { if(i%%2==0) { x[i] <- 2*x[i-1] } else { x[i] <- rnorm(1) } } }, ohne_schleife = { x <- rnorm(n) x[seq(2,n,2)] <- 2*x[seq(2,n,2)-1] }, ohne_schleife2 = { i <- seq(1,n,2) x[i] <- rnorm(length(i)) x[i+1] <- 2*x[i] })