2011-03-08 3 views
9

Me gustaría automatizar el proceso de creación de resultados cuando aplico ciertas técnicas de modelado. Así que tendré diferentes parámetros que se aplicarán (por ejemplo, distancias de agrupamiento jerárquicas y métodos de vinculación). Los resultados tendrán una forma de matriz para que pueda acceder a los resultados individuales al especificar los parámetros del modelo (por ejemplo, solo, euclidiano). En un marco de datos podría nombrar las columnas y filas y acceder a los elementos simplemente por df[rname[1],cname[1]]. Hasta donde he leído, no es posible usar objetos de marcos de datos para almacenar los resultados de la lista. Entonces necesito listas para almacenar los resultados de la lista. Pero en las listas solo puedo especificar lst$cname[1] y no ambas dimensiones. ¿Estoy en lo correcto?¿Cuál es una buena estrategia en R para almacenar resultados en forma de lista para acceder más tarde por nombres en lugar de índices?

# data frame layout for numeric results does not work with list results 
rname<-c("u","v","w") 
cname<-c("ave","single") 

# dataframe for results but does not work for results which are lists 
paste.1<-function(x,y) paste(x,y,sep=".") 
df1<-data.frame(lapply(cname,paste.1,x=rname),row.names=rname) 
colnames(df1)<-cname 

# creating list for results - do not get a good idea to proceed from here Advices?? 
lst<-(lapply(cname,paste.1,x=rname)) 
names(lst)<-cname 

# results example - could be anything else 
# with a dataframe I could use df1[rname,cname]<-foo(rname,cname) 
# with lists I guess its not as easy 
require(graphics) 
ave.u <- hclust(dist(USArrests,"euclidean"), cname[1]) 
ave.v <- hclust(dist(USArrests,"maximum"), cname[1]) 
ave.w <- hclust(dist(USArrests,"manhattan"), cname[1]) 
single.u <- hclust(dist(USArrests,"euclidean"), cname[2]) 
single.v <- hclust(dist(USArrests,"maximum"), cname[2]) 
single.w <- hclust(dist(USArrests,"manhattan"), cname[2]) 

Bueno, no estoy seguro de si hay una solución que supongo que debe existir. Al final solo quiero acceder a los resultados de la lista a través de los nombres de las filas y los nombres de las columnas. Sé que podría transferir nombres de fila/columna a numéricos y luego jugar asignando índices adecuados para encontrar mis resultados en una lista de longitud (rname) x longitud (cname) pero dado que el marco de datos es tan agradable de usar, lo estoy asumiendo debe ser una manera fácil de almacenarlo más fácil de usar. También podría ser que no haya entrado bien en el concepto de listas, ya que estoy empezando a jugar con R. Entonces mi pregunta es: ¿cuál sería una buena estrategia para almacenar los resultados estructurados (que son listas)? usando R?

+0

¿Es posible que realmente pueda convertirlo en un marco de datos?Por lo que yo entiendo, el marco de datos tiene que ser rectangular, mientras que la lista puede ser de cualquier dimensión. – Sam

+0

Los marcos de datos AFAIK en r se implementan como listas de la misma longitud. – richiemorrisroe

+2

Creo que esta pregunta es terriblemente confusa, especialmente el ejemplo. Una descripción clara de lo que estás tratando de lograr sería muy útil. – Ista

Respuesta

3

Uno puede tener una matriz de listas:

nr <- length(rname) 
nc <- length(cname) 

m <- matrix(list(), nr, nc, dimnames = list(rname, cname)) 

m[["u", "ave"]] <- ave.u 

# etc. 

Por ejemplo, formar los nombres de fila, rnm, y nombres de columna, cnm, y una trama de datos, g, de todas las combinaciones de sus valores. A continuación, crear una matriz de listas, m:

rnm <- c("euclidean", "maximum", "manhattan") 
cnm <- c("ave", "single") 
g <- expand.grid(rnm, cnm) 
f <- function(i) hclust(dist(USArrests, g[i,1]), g[i,2]) 
m <- matrix(lapply(1:nrow(g), f), length(rnm), dimnames = list(rnm, cnm)) 

podemos tener acceso a elementos de la siguiente manera:

> m[["euclidean", "single"]] 

Call: 
hclust(d = dist(USArrests, g[i, 1]), method = g[i, 2]) 

Cluster method : single 
Distance   : euclidean 
Number of objects: 50 
+0

Solución interesante, esto es en lo que estaba pensando pero no pude conseguir el camino para hacerlo funcionar. expand.grid() es bueno saberlo. La solución es similar a la sugerencia de James, pero de alguna manera me siento más cómodo con esa matriz. Gracias – Sebastian

3

Usted puede utilizar el operador $ en varias ocasiones, por ejemplo:

mname <-c("euclidean","maximum","manhattan") 
lst <- sapply(mname,function(x) sapply(cname,function(y) hclust(dist(USArrests,x),y),simplify=F),simplify=F) 
names(lst)<-rname 

Y que pueda utilice lo siguiente para referenciar,

lst$"u"$"ave" 

Call: 
hclust(d = dist(USArrests, x), method = y) 

Cluster method : average 
Distance   : euclidean 
Number of objects: 50 

Desafortunadamente, lst$rname[1]$cname[1] no funciona, pero se puede utilizar do.call:

do.call(`$`,list(do.call(`$`,list(lst,rname[1])),cname[1])) 

Call: 
hclust(d = dist(USArrests, x), method = y) 

Cluster method : average 
Distance   : euclidean 
Number of objects: 50 

Editar

No es en realidad una versión más simple, pero va a llevar a cabo sus llaves del soporte cuadrados!

lst[[rname[1]]][cname[1]] 
$ave 

Call: 
hclust(d = dist(USArrests, x), method = y) 

Cluster method : average 
Distance   : euclidean 
Number of objects: 50 

Editar 2

La notación de corchetes anterior parece envolver el objeto en un list lo que significa que no devuelve el objeto correctamente, pero la sugerencia de Hadley en los comentarios es más clara y evita este problema:

lst[[c(rname[1],cname[1])]] 
+1

Use 'lapply', not' sapply (..., simplify = F) '. También puede suministrar un vector a '[[': 'lst [[c (" u "," ave ")]]' – hadley

+0

@hadley Originalmente usé 'lapply', pero terminé usando' sapply' porque establece nombres automáticamente, y con 'simplify = F' es esencialmente lo mismo que' lapply'. Buen uso de usar un vector para '[[' es mucho más claro de leer y el método que publiqué envuelve el elemento en una 'lista' para que no devuelva un objeto' hclust'. – James

+0

Gracias. Exactamente la solución que estaba buscando. Gran ayuda. Solo necesita jugar para entender más la familia de funciones de aplicación. nunca habría encontrado la solución usando lst [[c (rname [1], cname [1])]] solo. Eso me ayudó mucho. – Sebastian

Cuestiones relacionadas