2011-05-09 15 views
9

Con frecuencia me encuentro con situaciones en las que necesito crear muchos modelos similares para diferentes variables. Por lo general, los vuelvo a la lista. Aquí está el ejemplo de código ficticio:Accediendo a los mismos elementos de listas con nombre de la lista de listas en R

modlist <- lapply(1:10,function(l) { 
    data <- data.frame(Y=rnorm(10),X=rnorm(10)) 
    lm(Y~.,data=data) 
}) 

Ahora conseguir el ajuste, por ejemplo, es muy fácil:

lapply(modlist,predict) 

Lo que quiero hacer a veces es extraer un elemento de la lista. La forma más obvia es

sapply(modlist,function(l)l$rank) 

Esto hace lo que yo quiero, pero me pregunto si hay un camino más corto para conseguir el mismo resultado?

+0

su código de ejemplo devuelve un error al utilizar el paquete foreach. –

+0

@Joris, es un código ficticio, no debería funcionar en principio, ya que 'simulate' no está definido. Sin embargo, hubo un error con 'C' en mayúscula. Gracias por mencionarlo. – mpiktas

+3

Ya veo. Sin embargo, las personas asumirán que su código falso se ejecuta, y un ejemplo reproducible mínimo es en general un pequeño esfuerzo para ilustrar un problema. Evita que tengamos que hacer uno nosotros mismos en busca de una respuesta. –

Respuesta

14

suelo usar kohske way, pero aquí hay otro truco:

sapply(modlist, with, rank) 

es más útil cuando se necesita más elementos, por ejemplo .:

sapply(modlist, with, c(rank, df.residual)) 

Como recuerdo lo robé a Hadley (a partir de la documentación plyr creo).

+2

gracias, esto sin duda se siente como @hadley code, simple y elegante. – mpiktas

+0

@mpiktas La diferencia principal entre las soluciones '" [["' y 'con' es en caso de que falten elementos. '" [["' devuelve 'NULL' cuando el elemento falta. 'con' arroja un error ** a menos que exista un objeto en el espacio de trabajo global con el mismo nombre que el elemento buscado **. Por ejemplo, 'dah <-1; lapply (modlist, with, dah)' devuelve la lista de unos cuando 'modlist' no tiene ningún elemento' dah'. – Marek

+0

gracias por el comentario adicional. En mi caso, los elementos de la lista no deberían tener elementos faltantes, por lo que los errores son bienvenidos. – mpiktas

24

probable que estos son un poco más simple:

> z <- list(list(a=1, b=2), list(a=3, b=4)) 
> sapply(z, `[[`, "b") 
[1] 2 4 
> sapply(z, get, x="b") 
[1] 2 4 

y se puede definir una función como:

> `%c%` <- function(x, n)sapply(x, `[[`, n) 
> z %c% "b" 
[1] 2 4 

y esto se ve como una extensión de $:

> `%$%` <- function(x, n) sapply(x, `[[`, as.character(as.list(match.call())$n)) 
> z%$%b 
[1] 2 4 
+1

Gracias, pensé que algo así debería ser posible. Es una lástima que no pueda aceptar ambas respuestas. Elegí la respuesta de @Marek solo por razones estéticas. He subido la tuya. – mpiktas

1

Con el nuevo paquete lowliner de Hadley puede suministrar map() con un índice numérico o un nombre de elemento para extraer componentes elegantemente de una lista. map() es el equivalente a lapply() con algunos trucos adicionales.

library("lowliner") 

l <- list(
    list(a = 1, b = 2), 
    list(a = 3, b = 4) 
) 

map(l, "b") 
map(l, 2) 

Hay también una versión que simplifica el resultado de un vector

map_v(l, "a") 
map_v(l, 1) 
Cuestiones relacionadas