2011-05-26 11 views
8

Esto es algo que los analistas de datos hacen todo el tiempo (especialmente cuando trabajan con datos de encuestas que tienen respuestas faltantes). Es común primero imputar un conjunto de matrices de datos compite, ajuste modelos a cada una de estas matrices y luego combine los resultados. Por el momento estoy haciendo cosas a mano y buscando una solución más elegante.Con R, recorra tramas de datos y asigne nombres apropiados a objetos creados en el bucle

imagino que hay 5 *.csv archivos en el directorio de trabajo, el nombre dat1.csv, dat2.csv, ... dat5.csv. Quiero estimar el mismo modelo lineal usando cada conjunto de datos.

Dada this answer, un primer paso es reunir una lista de los archivos, que hago con el siguiente

csvdat <- list.files(pattern="dat.*csv") 

Ahora quiero hacer algo como

for(x in csvdat) { 
    lm.which(csvdat == "x") <- lm(y ~ x1 + x2, data = x) 
} 

El "que" La declaración es mi tonta manera de intentar numerar cada modelo por turno, usando la ubicación en la lista csvdat que el ciclo está actualmente disponible. es decir, me gustaría que este bucle para devolver un conjunto de 5 lm objetos con los nombres lm.1, lm.2, etc

¿Hay alguna forma sencilla de crear estos objetos y nombrarlos para que pueda indicar fácilmente qué datos establecer que corresponden a?

Gracias por su ayuda!

Respuesta

10

Otro enfoque es utilizar el paquete plyr para realizar el bucle. Usando el ejemplo construido por @chl, aquí está cómo lo haría

require(plyr) 

# read csv files into list of data frames 
data_frames = llply(csvdat, read.csv) 

# run regression models on each data frame 
regressions = llply(data_frames, lm, formula = y ~ .) 
names(regressions) = csvdat 
+0

Solución más elegante que la mía. Mi +1 por venir, pero veo la respuesta de @Henrik, que es lo que el OP estaba buscando. – chl

+0

@ chi Tanto su solución como la de Ramnath servirán mejor al consultante a largo plazo. –

8

lo que quiere es una combinación de las funciones seq_along() y assign()

seq_along ayuda a crear un vector de 1 a 5 si hay cinco objetos en csvdat (para obtener los números apropiados y no sólo los nombres de las variables). Luego, assign (usando paste para crear los astrings apropiados a partir de los números) le permite crear la variable.

en cuenta que también tendrá que cargar el archivo de datos primero (que faltaba en el ejemplo):

for (x in seq_along(csvdat)) { 
    data.in <- read.csv(csvdat[x]) #be sure to change this to read.table if necessary 
    assign(paste("lm.", x, sep = ""), lm(y ~ x1 + x2, data = data.in)) 
} 

seq_along no es totalmente necesario, podría haber otras maneras de resolver el problema de numeración.

La función crítica es assign. Con la asignación puede crear variables con un nombre basado en una cadena. Consulte ?assign para obtener más información.


Siguiendo los comentarios de CHL (véase su puesto) todo en una sola línea:

for (x in seq_along(csvdat)) assign(paste("lm", x, sep = "."), lm(y ~ x1 + x2, data = read.csv(csvdat[x])) 
+0

Bueno, apunte a 'assign'. (Hoy no he votado, pero asegúrese de votar lo antes posible.) – chl

+0

Brillante, gracias Henrik. Una solución muy elegante. – tomw

10

utilizar una lista para almacenar los resultados de los modelos de regresión, así, por ejemplo,

foo <- function(n) return(transform(X <- as.data.frame(replicate(2, rnorm(n))), 
                 y = V1+V2+rnorm(n))) 
write.csv(foo(10), file="dat1.csv") 
write.csv(foo(10), file="dat2.csv") 
csvdat <- list.files(pattern="dat.*csv") 
lm.res <- list() 
for (i in seq(along=csvdat)) 
    lm.res[[i]] <- lm(y ~ ., data=read.csv(csvdat[i])) 
names(lm.res) <- csvdat 
+0

+1 que definitivamente es una buena manera de Rish. Pero, el OP quería variables individuales, por lo que 'assign' es el camino a seguir ... – Henrik

+0

@Henrik Agree. (Por cierto, podrías reemplazar tu comando 'paste' con' sep = "." ', pero no podré volver a votar más :-) – chl

+0

@chl buen punto con' sep = "." '. Además, cargar los datos en la llamada a 'lm' también es bastante limpio, creo (¡entonces uno podría poner todo en una sola línea!). – Henrik

Cuestiones relacionadas