varias superponer separar programacion por graficos graficas ejemplos contar comparar caracteres caracter cadenas r string formula paste names

superponer - ¿Cómo usar las variables de referencia por cadena de caracteres en una fórmula?



superponer graficas en r (2)

En el ejemplo mínimo a continuación, estoy tratando de usar los valores de un string string de caracteres en una fórmula de regresión. Sin embargo, solo puedo pasar la cadena de nombres de variables ("v2 + v3 + v4") a la fórmula, no el significado real de esta cadena (por ejemplo, "v2" es dat $ v2).

Sé que hay mejores formas de ejecutar la regresión (p. Ej., lm(v1 ~ v2 + v3 + v4, data=dat) ). Mi situación es más compleja y estoy tratando de descubrir cómo usar una cadena de caracteres en una fórmula. ¿Alguna idea?

Código actualizado a continuación

# minimal example # create data frame v1 <- rnorm(10) v2 <- sample(c(0,1), 10, replace=TRUE) v3 <- rnorm(10) v4 <- rnorm(10) dat <- cbind(v1, v2, v3, v4) dat <- as.data.frame(dat) # create objects of column names c.2 <- colnames(dat)[2] c.3 <- colnames(dat)[3] c.4 <- colnames(dat)[4] # shortcut to get to the type of object my full code produces vars <- paste(c.2, c.3, c.4, sep="+") ### TRYING TO SOLVE FROM THIS POINT: print(vars) # [1] "v2+v3+v4" # use vars in regression regression <- paste0("v1", " ~ ", vars) m1 <- lm(as.formula(regression), data=dat)

Actualización: @Arun tenía razón sobre el "" faltante en la v1 en el primer ejemplo. Esto solucionó mi ejemplo, pero todavía tenía problemas con mi código real. En el fragmento de código a continuación, adapté mi ejemplo para reflejar mejor mi código real. Elegí crear un ejemplo más simple al principio pensando que el problema era el string vars .

Aquí hay un ejemplo que no funciona :) Utiliza el mismo marco de datos dat creado anteriormente.

dv <- colnames(dat)[1] r2 <- colnames(dat)[2] # the following loop creates objects r3, r4, r5, and r6 # r5 and r6 are interaction terms for (v in 3:4) { r <- colnames(dat)[v] assign(paste("r",v,sep=""),r) r <- paste(colnames(dat)[2], colnames(dat)[v], sep="*") assign(paste("r",v+2,sep=""),r) } # combine r3, r4, r5, and r6 then collapse and remove trailing + vars2 <- sapply(3:6, function(i) { paste0("r", i, "+") }) vars2 <- paste(vars2, collapse = '''') vars2 <- substr(vars2, 1, nchar(vars2)-1) # concatenate dv, r2 (as a factor), and vars into `eq` eq <- paste0(dv, " ~ factor(",r2,") +", vars2)

Aquí está el problema:

print(eq) # [1] "v1 ~ factor(v2) +r3+r4+r5+r6"

A diferencia de la regression en el primer ejemplo, eq no trae los nombres de las columnas (p. Ej., v3 ). Los nombres de los objetos (p. Ej., r3 ) se conservan. Como tal, el siguiente comando lm() no funciona.

m2 <- lm(as.formula(eq), data=dat)


TL; DR: use paste .

create_ctree <- function(col){ myFormula <- paste(col, "~.", collapse="") ctree(myFormula, data) } create_ctree("class")


Veo un par de problemas pasando aquí. Primero, y no creo que esto esté causando ningún problema, pero hagamos su marco de datos en un solo paso para que no tenga v1 a v4 flotando tanto en el entorno global como en el marco de datos. En segundo lugar, hagamos que v2 un factor aquí, de modo que no tengamos que lidiar con hacerlo más tarde.

dat <- data.frame(v1 = rnorm(10), v2 = factor(sample(c(0,1), 10, replace=TRUE)), v3 = rnorm(10), v4 = rnorm(10) )

Parte Uno Ahora, para su primera parte, parece que esto es lo que quiere:

lm(v1 ~ v2 + v3 + v4, data=dat)

Aquí hay una forma más sencilla de hacerlo, aunque todavía debe especificar la variable de respuesta.

lm(v1 ~ ., data=dat)

Alternativamente, ciertamente puede construir la función con pegar y llamar a lm sobre ella.

f <- paste(names(dat)[1], "~", paste(names(dat)[-1], collapse=" + ")) # "v1 ~ v2 + v3 + v4" lm(f, data=dat)

Sin embargo, mi preferencia en estas situaciones es usar do.call , que evalúa expresiones antes de pasarlas a la función; esto hace que el objeto resultante sea más adecuado para funciones de llamada como update activada. Compare la parte call de la salida.

do.call("lm", list(as.formula(f), data=as.name("dat")))

Parte dos Sobre su segunda parte, parece que esto es lo que está buscando:

lm(factor(v2) + v3 + v4 + v2*v3 + v2*v4, data=dat)

En primer lugar, como v2 es un factor en el marco de datos, no necesitamos esa parte, y en segundo lugar, esto se puede simplificar aún más utilizando mejor los métodos de R para usar operaciones aritméticas para crear interacciones, como esta.

lm(v1 ~ v2*(v3 + v4), data=dat)

Simplemente crearía la función usando paste ; el bucle con assign , incluso en el caso más grande, probablemente no sea una buena idea.

f <- paste(names(dat)[1], "~", names(dat)[2], "* (", paste(names(dat)[-c(1:2)], collapse=" + "), ")") # "v1 ~ v2 * ( v3 + v4 )"

Luego se puede llamar usando lm directamente o con do.call .

lm(f, data=dat) do.call("lm", list(as.formula(f), data=as.name("dat")))

Acerca de su código El problema que tuvo al tratar de usar r3 etc. fue que quería el contenido de la variable r3 , no el valor r3 . Para obtener el valor, necesita get , como este, y luego colapsaría los valores junto con paste .

vars <- sapply(paste0("r", 3:6), get) paste(vars, collapse=" + ")

Sin embargo, una mejor manera sería evitar assign y simplemente construir un vector de los términos que desee, como este.

vars <- NULL for (v in 3:4) { vars <- c(vars, colnames(dat)[v], paste(colnames(dat)[2], colnames(dat)[v], sep="*")) } paste(vars, collapse=" + ")

Una solución más parecida a R sería usar lapply :

vars <- unlist(lapply(colnames(dat)[3:4], function(x) c(x, paste(colnames(dat)[2], x, sep="*"))))