2017-01-27 1 views
0

Ich arbeite gerade an meinem Weg durch das Buch 'R for Data Science'.Schreiben einer for-Schleife mit der Ausgabe als Datenrahmen in R

Ich versuche diese Übungsfrage (21.2.1 Q1.4) zu lösen, aber war nicht in der Lage, die richtige Ausgabe vor dem Start der for-Schleife zu bestimmen.

Schreiben Sie eine for-Schleife: generieren 10 zufällige Normalen für jeden von μ = -10, 0, 10 und 100.

Wie in den vorherigen Fragen in dem Buch, das ich versucht haben, einfügen in eine Vektorausgabe, aber für dieses Beispiel, es scheint, ich brauche die Ausgabe, um ein Datenrahmen zu sein?

Dies ist mein Code so weit:

values <- c(-10,0,10,100) 
output <- vector("double", 10) 

for (i in seq_along(values)) { 
    output[[i]] <- rnorm(10, mean = values[[i]]) 
} 

Ich weiß, dass der Ausgang falsch ist, aber ich bin nicht sicher, wie das Format, das ich hier erstellen müssen. Jede Hilfe wird sehr geschätzt. Vielen Dank!

+0

Sie können 'lapply' oder' sapply' dh 'd1 <- data.frame (lapply (Werte, Funktion (x) rnorm (10 , Mittelwert = x))); Spaltennamen (d1) <- paste0 ("V", seq_along (Werte)) ' – akrun

+0

Hallo, danke für deine Lösung, das funktioniert. b Es wäre aber auch gut, eine For-Loop-Lösung zu bekommen, da es sich um eine Fähigkeit handelt, die ich gerade verbessern möchte. Vielen Dank! – George

+0

Sie erstellen zunächst eine leere Matrix oder Liste und weisen ihr dann die Werte zu. h. "Ausgabe <- Vektor (" Liste ", 4)"; und verwenden Sie Ihren Code und 'cbind' oder' rbind', falls erforderlich, d. h. 'do.call (cbind, output)' – akrun

Antwort

2

Da dies eine Lernfrage ist, werde ich die Lösung nicht direkt bereitstellen.

> values <- c(-10,0,10,100) 
> for (i in seq_along(values)) {print(i)} # Checking we iterate by position 
[1] 1 
[1] 2 
[1] 3 
[1] 4 
> output <- vector("double", 10) 
> output # Checking the place where the output will be 
[1] 0 0 0 0 0 0 0 0 0 0 
> for (i in seq_along(values)) { # Testing the full code 
+  output[[i]] <- rnorm(10, mean = values[[i]]) 
+ } 
Error in output[[i]] <- rnorm(10, mean = values[[i]]) : 
    more elements supplied than there are to replace 

Wie Sie der Fehler dort sagen, sehen mehr Elemente als Raum zu stellen sind (jede Iteration erzeugt 10 Zufallszahlen (insgesamt 40) und Sie haben nur 10 Räume. Betrachten wir ein Datenformat, das erlaubt speichern mehrerer Werte für jede Iteration so dass:.

> output <- ?? 
> for (i in seq_along(values)) { # Testing the full code 
+  output[[i]] <- rnorm(10, mean = values[[i]]) 
+ } 
> output # Should have length 4 and each element all the 10 values you created in the loop 
+0

Verwenden Sie die obige Antwort von akrun: output <- vector ("list", 4). Würden Sie das tun? Danke für die gründliche Erklärung des Denkprozesses! Sehr hilfreich! – George

+0

Ja, oder einfach eine 'output <- list()' verwenden. Könnten Sie eine Antwort als die hilfreichste auswählen, indem Sie auf das Häkchen klicken? Auf diese Weise wird die Frage als gelöst markiert: D – Llopis

+0

Herzlichen Dank! – George

2

Es gibt viele Möglichkeiten, dies zu tun. Hier ist eine. Siehe Inline-Kommentare.

set.seed(357) # to make things reproducible, set random seed 

N <- 10 # number of loops 

xy <- vector("list", N) # create an empty list into which values are to be filled 

# run the loop N times and on each loop... 
for (i in 1:N) { 
    # generate a data.frame with 4 columns, and add a random number into each one 
    # random number depends on the mean specified 
    xy[[i]] <- data.frame(um10 = rnorm(1, mean = -10), 
         u0 = rnorm(1, mean = 0), 
         u10 = rnorm(1, mean = 10), 
         u100 = rnorm(1, mean = 100)) 
} 

# result is a list of data.frames with 1 row and 4 columns 

# you can bind them together into one data.frame using do.call 
# rbind means they will be merged row-wise 
xy <- do.call(rbind, xy) 

     um10   u0  u10  u100 
1 -11.241117 -0.5832050 10.394747 101.50421 
2 -9.233200 0.3174604 9.900024 100.22703 
3 -10.469015 0.4765213 9.088352 99.65822 
4 -9.453259 -0.3272080 10.041090 99.72397 
5 -10.593497 0.1764618 10.505760 101.00852 
6 -10.935463 0.3845648 9.981747 100.05564 
7 -11.447720 0.8477938 9.726617 99.12918 
8 -11.373889 -0.3550321 9.806823 99.52711 
9 -7.950092 0.5711058 10.162878 101.38218 
10 -9.408727 0.5885065 9.471274 100.69328 

Ein anderer Weg, um eine Matrix vorbelegen wäre, in Werten hinzuzufügen und es an einen data.frame zu zwingen.

xy <- matrix(NA, nrow = N, ncol = 4) 

for (i in 1:N) { 
    xy[i, ] <- rnorm(4, mean = c(-10, 0, 10, 100)) 
} 

# notice that i name the column names post festum 
colnames(xy) <- c("um10", "u0", "u10", "u100") 
xy <- as.data.frame(xy) 
0
# set the number of rows 
rows <- 10 

# vector with the values 
means <- c(-10,0,10,100) 

# generating output matrix 
output <- matrix(nrow = rows, 
      ncol = 4) 

# setting seed and looping through the number of rows 
set.seed(222) 
for (i in 1:rows){ 
    output[i,] <- rnorm(length(means), 
        mean=means) 
} 

#printing the output 
output 
Verwandte Themen