studio paquetes org library language for r names lapply

paquetes - r packages list



Acceda y conserve los nombres de las listas en la funciĆ³n lapply (5)

Necesito acceder a los nombres de lista dentro de la función lapply. He encontrado algunos subprocesos en línea donde se dice que debo recorrer los nombres de la lista para poder obtener el nombre de cada elemento de la lista en mi función:

> n = names(mylist) > mynewlist = lapply(n, function(nameindex, mylist) { return(mylist[[nameindex]]) }, mylist) > names(mynewlist) NULL > names(mynewlist) = n

El problema es que mynewlist pierde los índices de mylist originales y tengo que agregar esa asignación de apellidos () para restaurarlos.

¿Hay una manera de dar un nombre de índice explícito a cada elemento devuelto por la función lapply? ¿O una forma diferente de asegurarse de que los elementos de mynewlist tengan los nombres de índice correctos establecidos? Creo que los nombres de los índices de mynewlist podrían estar equivocados si lapply no devuelve los elementos de la lista en el mismo orden que mylist.


¿Has mirado en llply() desde el paquete plyr ?

Hace exactamente lo que estás pidiendo. Para cada elemento de una lista, aplique la función, manteniendo los resultados como una lista. llply es equivalente a lapping, excepto que conservará las etiquetas y puede mostrar una barra de progreso. de ?llply

mylist <- list(foo1=1:10,foo2=11:20) >names(mylist) [1] "foo1" "foo2" newlist<- llply(mylist, function(x) mean(x)) >names(newlist) [1] "foo1" "foo2"


Basándose en la respuesta de joran, y precisándola:

La sapply(USE.NAMES=T) hecho establecerá como nombres del resultado final los valores del vector sobre el que está iterando (y no sus nombres de atributos como lapply), pero solo si estos son caracteres.

Como resultado, los índices de paso no ayudarán. Si desea pasar índices con sapply , debe recurrir a algunos lanzamientos (feos):

sapply(as.character(c(1,11)), function(i) TEST[[as.numeric(i)]], USE.NAMES = TRUE)

En este caso, una solución más limpia es establecer y utilizar directamente los nombres de su objeto original. Aquí hay una lista exhaustiva de soluciones:

TEST <- as.list(LETTERS[1:12]) ### lapply ## ## Not working because no name attribute lapply(c(1,11), function(i) TEST[[i]]) ## working but cumbersome index <- c(1,11) names(index) <- index lapply(index, function(i) TEST[[i]]) ### sapply ## ## Not working because vector elements are not strings sapply(c(1,11), function(i) TEST[[i]], simplify = F) ## Working with the casting trick sapply(as.character(c(1,11)), function(i) TEST[[as.numeric(i)]], simplify = F) ## Cleaner, using names with sapply: names(TEST) <- LETTERS[26:15] sapply(names(TEST)[c(1,11)], function(name) TEST[[name]], simplify = F)


Creo que de lapply predeterminada, lapply mantiene el atributo de nombres de todo lo que está iterando. Cuando almacena los nombres de myList en n , ese vector ya no tiene ningún "nombre". Así que si añades eso de nuevo a través de,

names(n) <- names(myList)

y el uso lapply como antes, debe obtener el resultado deseado.

Editar

Mi cerebro está un poco brumoso esta mañana. Aquí hay otra opción, quizás más conveniente:

sapply(n,FUN = ...,simplify = FALSE,USE.NAMES = TRUE)

Estaba buscando a tientas, confundido de que lapply no tenía un argumento de USE.NAMES , y luego realmente miré el código en busca de sapply y me di cuenta de que estaba siendo tonto, y esta era probablemente una mejor manera de hacerlo.


La función setNames es un atajo útil aquí.

mylist <- list(a = TRUE, foo = LETTERS[1:3], baz = 1:5) n <- names(mylist) mynewlist <- lapply(setNames(n, n), function(nameindex) {mylist[[nameindex]]})

que conserva los nombres

> mynewlist $a [1] TRUE $foo [1] "A" "B" "C" $baz [1] 1 2 3 4 5


imap() del paquete purrr es bueno para su problema.

library(purrr) mylist <- list(foo1=1:10,foo2=11:20) imap(mylist, function(x, y) mean(x)) ## x is the value, y is the name

o puedes usar una versión más compacta de imap:

imap(mylist, ~ mean(.x))

Tenga en cuenta que puede utilizar variaciones de imap_xxx dependiendo del tipo de vector que desee:

imap_dbl(mylist, ~ mean(.x)) ## will return a named numeric vector.