2017-06-13 1 views
0

Ich möchte for() Schleife verwenden, um die gleiche Operation zu automatisieren, die über viele Variablen ausgeführt wird, die sie ändern.Verwenden von für() über Variablen, die geändert werden müssen

Hier einfachste Beispiel entwerfen könnte:

varToChange = list(1:10, iris$Species[1:10], letters[1:10]) # assume that it has many more than just 3 elements 
varToChange 
for (i in varToChange) { 
    if (is.character(y)) i <- as.integer(as.ordered(i)) 
    if (is.factor(y)) i <- as.integer(i) 
} 
varToChange # <-- Here I want to see my elements as integers now 

Hier ist aktuelles Beispiel, das mich zu dieser Frage geführt - entnommen aus: Best way to plot automatically all data.table columns using ggplot2

In der folgenden Funktion

f <- function(dt, x,y,k) { 
    if (is.numeric(x)) x <- names(dt)[x] 
    if (is.numeric(y)) y <- names(dt)[y] 
    if (is.numeric(k)) k <- names(dt)[k] 

ggplot(dt, aes_string(x,y, col=k)) + geom_jitter(alpha=0.1) 
} 
f(diamonds, 1,7,2) 

statt brutal von Ich wiederhole die gleiche Zeile oft, als Programmierer würde ich lieber eine Schleife haben, um diese Zeile für mich zu wiederholen. So etwas wie diese:

for (i in c(x,y,k)) { 
    if (is.numeric(i)) i <- names(dt)[i] 
} 

In C/C++ dies hätte mit Zeigern getan. In R - ist alles möglich?

UPDATE: Sehr nette Idee, Karte unten zu verwenden. Allerdings funktioniert es nicht für dieses Beispiel

getColName <- function(dt, x) { 
    if (is.numeric(x)) { 
    x <- names(dt)[x] 
    } 
    x 
} 

f<- function(dt, x,y,k) { 
    list(x,y,k) <- Map(getColName, list(x,y,k), dt) 
    # if (is.numeric(x)) x <- names(dt)[x] 
    # if (is.numeric(y)) y <- names(dt)[y] 
    # if (is.numeric(k)) k <- names(dt)[k] 

    ggplot(dt, aes_string(x,y, col=k)) + geom_jitter(alpha=0.1) 
} 
f(diamonds, 1,7,2) # Brrr.. 

Antwort

3

Keine Notwendigkeit für for-Schleife, Karte nur eine Funktion über jede Ihrer Listenelemente

varToChange = list(1:10, iris$Species[1:10], letters[1:10])  
myfun <- function(y) { 
    if (is.character(y)) y <- as.integer(as.ordered(y)) 
    if (is.factor(y)) y <- as.integer(y) 
    y 
} 
varToChange <- Map(myfun, varToChange) 

UPDATE: Karte nie Variablen anstelle ändert, Das ist einfach die neuen Werte zurück von Map

f<- function(dt, x, y, k) { 
    args <- Map(function(x) getColName(dt, x), list(x=x,y=y,k=k)) 

    ggplot(dt, aes_string(args$x,args$y, col=args$k)) + geom_jitter(alpha=0.1) 
} 
f(diamonds, 1,7,2) 
1

Sie haben zwei Möglichkeiten für Iteration in R nicht in R. Verwenden Sie fertig, iterieren Variablen selbst oder über ihre Indizes. Ich empfehle generell, über Indizes zu iterieren. Dieser Fall zeigt einen starken Vorteil, da Ihre Frage kein Problem ist, wenn Sie Indizes verwenden.

varToChange = list(1:10, iris$Species[1:10], letters[1:10]) 
for (i in seq_along(varToChange)) { 
    if (is.character(varToChange[[i]])) varToChange[[i]] <- as.integer(as.factor(varToChange[[i]])) 
    if (is.factor(varToChange[[i]])) varToChange[[i]] <- as.integer(varToChange[[i]]) 
} 

I ersetzt auch as.ordered() mit as.factor() - der einzige Unterschied zwischen einem geordneten Faktor und einem regulären Faktor sind die Standard-Kontraste in der Modellierung verwendet. Da Sie nur auf Integer gezwungen werden, spielt es keine Rolle.

Verwandte Themen