2010-12-08 22 views
7

Tengo un vector como estoconvertir un vector a una lista

c("1", "a","b") 

y me gustaría crear esta lista

list("a"=1,"b"=1) 

hay una manera de hacerlo en un "aplicar" ¿estilo? Gracias.

-k

+0

¿Hola Khanh - un valor, dos etiquetas? Eso parece extraño. –

+0

Necesito una consulta rápida, como una tabla hash. En este caso, "a" y "b" son nodos en una red, y 1 es su identificación de comunidad. ¿Es eficiente? – knguyen

Respuesta

7

como esta?

R> kn <- c("1", "a", "b") 
R> nl <- vector(mode="list", length=length(kn)-1) 
R> names(nl) <- kn[-1] 
R> nl <- lapply(nl, function(x) kn[1]) 
R> nl 
$a 
[1] "1" 

$b 
[1] "1" 

R> 

Con felicitaciones a Gavin para la detección de un error anterior .

+0

@Dirk: 'kn' no tiene ningún nombre, y ¿el paso' lapply' no sobrescribirá 'nl' para configurar los nombres antes de que no los peguen? –

+0

Literalmente copié lo que funcionaba en mi caparazón. –

+0

Err, no, estabas en lo cierto. Corregido, re-ejecutado y editado. Gracias por detectar eso. –

5

No se aplica un estilo, sino una simple función para envolver los comandos requeridos es:

makeList <- function(vec) { 
    len <- length(vec[-1]) 
    out <- as.list(rep(as.numeric(vec[1]), len)) 
    names(out) <- as.character(vec[-1]) 
    out 
} 

Usando su vector, que da:

> vec <- c("1", "a","b") 
> makeList(vec) 
$a 
[1] 1 

$b 
[1] 1 
+1

Puede querer 'as.numeric' el" 1 " –

+0

@Joshua; ¡woops! Bien descrito. –

10

Usando as.list y setNames:

x = c("1", "a","b") 
as.list(setNames(rep(as.numeric(x[1]), length(x) - 1), x[-1])) 
+0

__________neat! –

+2

ya que encontré esta pregunta mientras buscaba una solución para el caso más general de convertir un vector a una lista con nombre, solo quería agregar que también puede hacer esto si no le importa que los nombres sean los mismos que los contenidos: 'as.list (setNames (x, x))' – user5359531

2

Para completar, hay una línea más simple para hacerlo en una "aplicación "Estilo Ly conforme a lo solicitado:

as.list(sapply(x[-1],function(y) as.double(x[1]))) 

Aunque no es la opción más rápida, sin duda es lo suficientemente limpio como para merecer su lugar como una respuesta a la pregunta. Es posible una aceleración significativa sin simplificar innecesariamente un vector:

library(microbenchmark) 
    microbenchmark(times=20, 
       Charles=as.list(setNames(rep(as.numeric(x[1]), length(x) - 1), x[-1])), 
       Gavin=makeList(x), 
       Anon=sapply(x[-1],function(y) as.double(x[1]),simplify=FALSE) 
) 

Unit: microseconds 
    expr min  lq median  uq max neval 
Charles 10.868 11.7735 11.774 12.3775 55.848 20 
    Gavin 12.075 12.6795 13.132 13.8870 26.867 20 
    Anon 6.643 7.0950 7.548 8.1520 17.811 20 
+0

En lugar de 'as.list (sapply (...))', use 'sapply (..., simplify = FALSE)'. –

+0

Sin simplify = F, tendremos idéntico (Charles, Anon) = FALSE, que no quería. Con simplify = F, tu sugerencia te lleva a una mayor aceleración --- He actualizado mi respuesta. Gracias. – andrekos

Cuestiones relacionadas