2017-07-09 3 views
0

Ich bin neu in R (Economist mit Hintergrund in Stata) und ich habe Probleme, eine geschachtelte for-Schleife für mich arbeiten zu lassen. Ich weiß, das Problem ist, dass ich kein gutes Verständnis davon habe, wie man den Schleifenzähler als Teil eines Variablennamens verwendet.Erstellen neuer Spalten mit einer for-Schleife

Ein bisschen Hintergrund. Ich habe Datenrahmen mit Daten über durchschnittliche Mietpreise für Häuser unterschiedlicher Größe (1 Schlafzimmer, 2 Schlafzimmer, etc) und Daten zum Jahreseinkommen (Mittelwert, Median und verschiedene Perzentile). Ich versuche, eine Reihe neuer Spalten zu erzeugen, die das Verhältnis dieser beiden Dinge (Mietpreis/Durchschnittseinkommen) enthalten.

Insbesondere meine Variablen sind:

  • beds1, beds2, beds3, beds4

  • mean, median, p10, p25, p75, p90

Sie sehen also, ich 24 neue Spalten der Kosten/Ertragsdaten erzeugen müssen. Ich könnte 24 Zeilen Code schreiben, aber ich will nicht. Noch wichtiger ist, ich möchte eine effiziente Art und Weise lernen, dies in R zu tun. In Stata könnte ich dies sehr einfach mit einer verschachtelten for-Schleife tun, aber ich kann es nicht in R arbeiten. Hier ist mein Code so weit.

for (i in 1:4) { 
    stat <- c("median", "mean", "p10", "p25", "p75","p90") 
    for (x in stat) { 
     df$beds[i]_[x] <- round((df$beds[i]/df$[x]),digits=3) 
    } 
} 

Wenn ich diesen Code ausführen die Fehler, die ich bekommen ist

Error: unexpected input in: 
" for (x in stat) { 
    df$beds[i]_" 
>  } 
Error: unexpected '}' in " }" 
> } 
Error: unexpected '}' in "}" 

ich versucht habe [[]] die doppelte eckige Klammern zu verwenden, aber das hat nicht die Ergebnisse ändern. Wenn jemand etwas darüber weiß, warum die Namen der dynamischen Variablen nicht funktionieren, lassen Sie es mich bitte wissen. Noch besser, da ich glaube, dass Schleifen in R böse sind, wenn jemand einen Weg kennt, um dies zu tun, würde ich das auch gern hören.


EDIT

Dank @Spacedman für den Kommentar. Ich denke, ich verstehe, was du sagst. Bedeutet das also, dass es einfach nicht zu tun ist, was ich in R machen will?

var1 <- c("beds1", "beds2") 
var2 <- c("mean", "median") 

for (i in 1:2) { 
    for (j in 1:2) { 
     df$var1[i]_var2[j] <- df$var1[i]/df$var2[j] 
    } 
} 

Ich denke, das var1 und var2 die Elemente der Listen greifen sollte, so dass, wenn i=1 und j=1, df$var1[i]/df$var2[j]df$beds1/df$mean bedeuten sollte. Oder würde R verrückt werden und denken, dass ich versuche, Streicher zu teilen?


FINAL EDIT MIT ANTWORT VON @SPACEEMAN

Dank @Spacedman. Ich habe deinen Spoiler geliebt und danke, dass du zusätzliche Hilfe geleistet hast. Ich habe den Unterschied zwischen den beiden Arten, nach dem letzten Beitrag auf die Spalten zu verweisen, nicht ganz verstanden, aber ich denke, ich habe jetzt eine bessere Idee. Ich habe ein bisschen optimiert und jetzt habe ich etwas, das perfekt funktioniert. Danke noch einmal!

beds <- c("beds1", "beds2", "beds3", "beds4") 
stat <- c("median", "mean", "p10", "p25", "p75","p90") 

for(i in beds){ 
    for(x in stat){ 
     res = paste0(i,"_",x) 
     df[[res]]=round(df[[i]]/df[[x]],digits=3) 
    } 
} 

Antwort

2

R ist keine Makroerweiterung Sprache wie andere Sprachen, die Sie verwendet werden könnten.

x[i], wenn i=123, "expandiert" nicht in x123.Es erhält den Wert des 123. Elements des Vektors x.

So df$beds[i] versucht, das i-te Element eines Vektors df$beds zu bekommen.

Sie müssen zwei Dinge wissen:

  1. Wie konstruieren Strings aus anderen Saiten.

Hierfür können Sie paste0 verwenden:

> for(i in 1:4){ 
+ print(paste0("beds",i)) 
+ } 
[1] "beds1" 
[1] "beds2" 
[1] "beds3" 
[1] "beds4" 
  1. Wie von Namen Spalten zuzugreifen.

Dafür können Sie doppelte eckige Klammern verwenden. In einer Liste:

> z = list() 
> n = "thing" 

Doppelte Squabs werten ihren Index aus und verwenden diesen. Also:

> z[[n]] = 99 

Wird z$thing gesetzt, aber Dollarzeichen Indizierung ist wörtlich, so:

> z$n = 123 

z$n gesetzt wird:

> z 
$thing 
[1] 99 

$n 
[1] 123 

hoffentlich, dass genügend Hinweise gibt Ihnen durchzukommen. Es sollte alles in grundlegenden R Tutorials online behandelt werden.

Spoiler

Wenn Sie herausfinden wollen, wie es selbst zu tun, schauen jetzt weg ...

Zuerst lässt einen Beispieldatenrahmen erstellen - Sie sollten so etwas wie dies in Ihrer Frage sind so Wir haben gemeinsame Testdaten, um daran zu arbeiten. Ich habe nur drei Betten und zwei Werte:

> df = data.frame(
    beds1=c(1,2,3), 
    beds2=c(5,2,3), 
    beds3=c(6,6,6), 
    mean=c(8,4,3), 
    median=c(1,7,4)) 
> df 
     beds1 beds2 beds3 mean median 
    1  1  5  6 8  1 
    2  2  2  6 4  7 
    3  3  3  6 3  4 

Jetzt die Arbeit. Wir schleifen über die Bettnummer und die Charakterstatistik. Der Bettenspaltenname wird in bed gespeichert, indem "Betten" in die Nummer i eingefügt werden. Wir berechnen den Namen der Ergebnisspalte (res) für eine gegebene Bettnummer und stat, indem Sie "beds" in i und "_" und den Namen des Stat in x einfügen.

Setzen Sie die neue Ergebnisspalte auf den Wert, indem Sie die Anzahl der Betten durch die Statistik dividieren. Wir verwenden [[z]] die Spalten nach Namen zu bekommen:

> for(i in 1:3){ 
    stats=c("mean","median") 
    for(x in stats){ 
    bed = paste0("beds",i) 
    res = paste0("beds",i,"_",x) 
    df[[res]]=round(df[[bed]]/df[[x]],digits=3) 
    } 
} 

Resultierende in ....

> df 
    beds1 beds2 beds3 mean median beds1_mean beds1_median beds2_mean beds2_median 
1  1  5  6 8  1  0.125  1.000  0.625  5.000 
2  2  2  6 4  7  0.500  0.286  0.500  0.286 
3  3  3  6 3  4  1.000  0.750  1.000  0.750 
    beds3_mean beds3_median 
1  0.75  6.000 
2  1.50  0.857 
3  2.00  1.500 
> 
+0

bearbeiten. Kommentar zur Frage verschoben, weil die Formatierung nicht funktioniert hat. – JMac

Verwandte Themen