2012-09-20 35 views
16

Tengo una función que contiene un bucle en dos listas y crea algunos datos calculados. Me gustaría devolver estos datos como listas de listas, indexadas por algún valor, pero estoy obteniendo la asignación incorrecta.Crear una lista en un bucle en R - obtener nombres de elementos correctos

Un ejemplo mínima de lo que estoy tratando de hacer, y dónde estoy saliendo mal sería:

mybiglist <- list() 
for(i in 1:5){ 
    a <- runif(10) 
    b <- rnorm(16) 
    c <- rbinom(8, 5, i/10) 
    name <- paste('item:',i,sep='') 
    tmp <- list(uniform=a, normal=b, binomial=c) 
    mybiglist[[name]] <- append(mybiglist, tmp) 
} 

Si ejecuta este y mirar el mybiglist de salida, se verá que es algo va muy mal en la forma en que se nombra cada elemento.

¿Alguna idea sobre cómo podría lograr lo que realmente quiero?

Gracias

ps. Sé que en R hay un sentido en el que uno ha fallado si uno tiene que recurrir a los bucles, pero en este caso me siento justificado ;-)

+4

'c' no es una buena cosa nombrar un objeto !! – BenBarnes

+0

De hecho ... ¡punto tomado! Thx – Hassantm

Respuesta

31

Funciona si no usa el comando append:

mybiglist <- list() 
for(i in 1:5){ 
    a <- runif(10) 
    b <- rnorm(16) 
    c <- rbinom(8, 5, i/10) 
    name <- paste('item:',i,sep='') 
    tmp <- list(uniform=a, normal=b, binomial=c) 
    mybiglist[[name]] <- tmp 
} 

# List of 5 
# $ item:1:List of 3 
# ..$ uniform : num [1:10] 0.737 0.987 0.577 0.814 0.452 ... 
# ..$ normal : num [1:16] -0.403 -0.104 2.147 0.32 1.713 ... 
# ..$ binomial: num [1:8] 0 0 0 0 1 0 0 1 
# $ item:2:List of 3 
# ..$ uniform : num [1:10] 0.61 0.62 0.49 0.217 0.862 ... 
# ..$ normal : num [1:16] 0.945 -0.154 -0.5 -0.729 -0.547 ... 
# ..$ binomial: num [1:8] 1 2 2 0 2 1 0 2 
# $ item:3:List of 3 
# ..$ uniform : num [1:10] 0.66 0.094 0.432 0.634 0.949 ... 
# ..$ normal : num [1:16] -0.607 0.274 -1.455 0.828 -0.73 ... 
# ..$ binomial: num [1:8] 2 2 3 1 1 1 2 0 
# $ item:4:List of 3 
# ..$ uniform : num [1:10] 0.455 0.442 0.149 0.745 0.24 ... 
# ..$ normal : num [1:16] 0.0994 -0.5332 -0.8131 -1.1847 -0.8032 ... 
# ..$ binomial: num [1:8] 2 3 1 1 2 2 2 1 
# $ item:5:List of 3 
# ..$ uniform : num [1:10] 0.816 0.279 0.583 0.179 0.321 ... 
# ..$ normal : num [1:16] -0.036 1.137 0.178 0.29 1.266 ... 
# ..$ binomial: num [1:8] 3 4 3 4 4 2 2 3 
+1

ahhh ... ¡me gana por 3 segundos! – seancarmody

+0

Eso estuvo cerca ... –

+0

¡Lo siento, me he perdido! ¡Gracias a ambos! – Hassantm

4

Cambio

mybiglist[[name]] <- append(mybiglist, tmp) 

a

mybiglist[[name]] <- tmp 
+1

Gracias Sean ... ¡Eso hizo el truco! – Hassantm

1

para demostrar que un expli cit de bucle no se requiere

unif_norm <- replicate(5, list(uniform = runif(10), 
    normal = rnorm(16)), simplify=F) 

binomials <- lapply(seq_len(5)/10, function(prob) { 
list(binomial = rbinom(n = 5 ,size = 8, prob = prob))}) 

biglist <- setNames(mapply(c, unif_norm, binomials, SIMPLIFY = F), 
        paste0('item:',seq_along(unif_norm))) 

En general si vas por el camino for bucle es mejor preasignar la lista de antemano. Esto es más eficiente con la memoria.

mybiglist <- vector('list', 5) 
names(mybiglist) <- paste0('item:', seq_along(mybiglist)) 
for(i in seq_along(mybiglist)){ 
    a <- runif(10) 
    b <- rnorm(16) 
    c <- rbinom(8, 5, i/10) 

    tmp <- list(uniform=a, normal=b, binomial=c) 
    mybiglist[[i]] <- tmp 
} 
+0

Gracias ... aunque no quiero crear listas de distribuciones uniformes, normales y binomiales ;-) Fue la convención de nomenclatura que estaba buscando. – Hassantm

+0

¡Al menos recuerda preasignar! – mnel

Cuestiones relacionadas