2017-03-31 2 views
0

Ich lerne R und habe meine erste for-Schleife geschrieben. Für 1000 Iterationen erstelle ich 4 Vektoren mit den Dimensionen 10, 100, 1000 und 10000 Elementen. Diese sogenannten Theta1-Werte werden nicht erkannt. Ich habe versucht, einen Theta1 zu der Zeit zu laufen, und es funktioniert, aber das Ausführen aller 4 gibt den Fehler 'Objekt nicht gefunden'. Es ist nicht offensichtlich für mich, was hier falsch ist, kann jemand erklären?For Schleife in R Rückgabe Fehler 'Objekt nicht gefunden'

k=1000 

'Method1' 

for(i in 1:k){ 
    N10=runif(10) 
    N100=runif(100) 
    N1000=runif(1000) 
    N10000=runif(10000) 
    theta1_10[i]=(1/10)*4*sum(sqrt(1-N10^2)) 
    theta1_100[i]=(1/100)*4*sum(sqrt(1-N100^2)) 
    theta1_1000[i]=(1/1000)*4*sum(sqrt(1-N1000^2)) 
    theta1_10000[i]=(1/10000)*4*sum(sqrt(1-N10000^2)) 
} 

'Result Method 1' 
m_theta1_10 = mean(theta1_10) 
sd_theta1_10 = sd(theta1_10) 
m_theta1_100 = mean(theta1_100) 
sd_theta1_100 = sd(theta1_100) 
m_theta1_1000 = mean(theta1_1000) 
sd_theta1_1000 = sd(theta1_1000) 
m_theta1_10000 = mean(theta1_10000) 
sd_theta1_10000 = sd(theta1_10000) 
+0

Was ist ' 'Methode 1'? Sie codieren nicht in 'vba'. Wenn Sie einen Kommentar wünschen, verwenden Sie stattdessen '#'! Das ist jedoch nicht dein Problem. – Masoud

+2

Sie müssen 'theta1_10' zu' theta1_100000' vor der for-Schleife initialisieren. Zum Beispiel 'theta1_10 = vector (, k)' – TooYoung

+1

Mögliches Duplikat von [So erstellen Sie einen leeren R-Vektor, um neue Elemente hinzuzufügen] (http://stackoverflow.com/questions/3413879/how-to-create-an-empty -r-vector-to-add-new-items) – vincentmajor

Antwort

1

Sie müssen einen Vektor initialisieren, bevor Sie ihm Werte zuweisen. Für diesen Fall ist es:

# Initialize 
k=1000 
theta1_10 = vector(,k) 
theta1_100 = vector(,k) 
theta1_1000 = vector(,k) 
theta1_10000 = vector(,k) 

# Method1 
for(i in 1:k){ 
    N10=runif(10) 
    N100=runif(100) 
    N1000=runif(1000) 
    N10000=runif(10000) 
    theta1_10[k] = (1/10)*4*sum(sqrt(1-N10^2)) 
    theta1_100[k] = (1/100)*4*sum(sqrt(1-N100^2)) 
    theta1_1000[k] = (1/1000)*4*sum(sqrt(1-N1000^2)) 
    theta1_10000[k] = (1/10000)*4*sum(sqrt(1-N10000^2)) 
} 

# Result Method 1 
result = data.frame(mean = c(mean(theta1_10),mean(theta1_100),mean(theta1_1000),mean(theta1_10000)), 
        sd = c(sd(theta1_10),sd(theta1_100),sd(theta1_1000),sd(theta1_10000))) 
rownames(result) <- c("theta1_10","theta1_100","theta1_1000","theta1_10000") 
result 

       mean   sd 
theta1_10 3.145259 0.287263626 
theta1_100 3.142640 0.089207786 
theta1_1000 3.140476 0.027901399 
theta1_10000 3.141695 0.009046627 
+0

Danke, die Zuweisung eines Vektors hat den Deal gemacht. Um besser zu verstehen, ist theta1_10 als Parameter in theta1_10 = c (theta1_10, (1/10) * 4 * Summe (sqrt (1-N10^2))) an den Vektor theta1_10 angefügt? – Orongo

+0

Ja, 'c (theta1_10, ....)' bedeutet folgendes an 'theta1_10' anhängen. Und wie Uwe Block darauf hingewiesen hat, ist es keine gute Idee, wenn k groß ist. – TooYoung

1

Ich schreibe diese Antwort, weil sowohl die Frage als auch die Antwort akzeptiert schlechten Programmierstil in R demonstrieren: Sie sind für die Schleife einen Vektor in einem wächst. (Siehe Circle 2

Der Effekt wird aus einem einfachen Benchmark deutlich werden. Die Aufgabe ist es, einen Vektor x zu schaffen, die die ganzzahlige Zahlen von 1 bis k enthalten:

k <- 10000L 
microbenchmark::microbenchmark(
    grow = { 
    x <- integer(0) 
    for (i in seq.int(k)) x <- c(x, i) 
    x 
    }, 
    subscript = { 
    x <- integer(k) 
    for (i in seq.int(k)) x[i] <- i 
    x 
    }, 
    colon_operator = { 
    x <- 1L:k 
    x 
    }, 
    times = 10L 
) 
#Unit: microseconds 
#   expr  min  lq  mean median  uq  max neval 
#   grow 93491.676 96127.568 104219.0140 97123.627 99459.343 165545.063 10 
#  subscript 9067.607 9215.996 9483.0962 9551.288 9771.795 9938.307 10 
# colon_operator  5.664  7.552  7.9675  8.307  8.685  9.063 10 

Es ist offensichtlich, dass auch bei einem kleinen Vektor der Länge 10000 Anfügen Elemente ist eine Größenordnung langsamer ist als zuvor die erforderliche Länge zuordnet. Das Timing des Doppelpunktoperators ist hier enthalten, um den Nutzen der integrierten vektorisierten Funktionen zu demonstrieren.

Also beide Codes in Frage und answer müssen neu geschrieben werden, um Subskribierung zu verwenden, um die Effizienz zu verbessern.

# initialize the random number generator for reproducible results 
set.seed(1234L) 
# allocate memory for the vectors beforehand 
theta1_10 = numeric(k) 
theta1_100 = numeric(k) 
theta1_1000 = numeric(k) 
theta1_10000 = numeric(k) 

# Method1 
for(i in seq.int(k)){ 
    N10=runif(10) 
    N100=runif(100) 
    N1000=runif(1000) 
    N10000=runif(10000) 
    # update by subscripting 
    theta1_10[i] = (1/10)*4*sum(sqrt(1-N10^2)) 
    theta1_100[i] = (1/100)*4*sum(sqrt(1-N100^2)) 
    theta1_1000[i] = (1/1000)*4*sum(sqrt(1-N1000^2)) 
    theta1_10000[i] = (1/10000)*4*sum(sqrt(1-N10000^2)) 
} 

kann jedoch der gesamte Code in einer viel prägnanter Weise neu geschrieben werden:

library(data.table) 
set.seed(1234) 
k <- 1000L 
N <- 10^(1:4) 
rbindlist(
    lapply(N, function(i) { 
    theta1 <- replicate(k, 4/i * sum(sqrt(1 - runif(i)^2))) 
    data.table(N = i, mean = mean(theta1), sd = sd(theta1)) 
    })) 
#  N  mean   sd 
#1: 10 3.144974 0.27238683 
#2: 100 3.140716 0.09040696 
#3: 1000 3.141791 0.02654225 
#4: 10000 3.141585 0.00886737 
Verwandte Themen