vapply usar language functions funciones funcion data como r lapply

usar - r language apply data frame



lapply con la funciĆ³n "$" (2)

Para el primer ejemplo, puedes hacer:

lapply(dflist, `$.data.frame`, "a")

Para el segundo, use la función de acceso a la slot()

lapply(mylist, "slot", "tab")

No estoy seguro de por qué el envío de métodos no funciona en el primer caso, pero la sección Note de ?lapply aborda este mismo problema de su envío de métodos borked para funciones primitivas como $ :

Note: [...] For historical reasons, the calls created by ‘lapply’ are unevaluated, and code has been written (e.g., ‘bquote’) that relies on this. This means that the recorded call is always of the form ‘FUN(X[[i]], ...)’, with ‘i’ replaced by the current (integer or double) index. This is not normally a problem, but it can be if ‘FUN’ uses ‘sys.call’ or ‘match.call’ or if it is a primitive function that makes use of the call. This means that it is often safer to call primitive functions with a wrapper, so that e.g. ‘lapply(ll, function(x) is.numeric(x))’ is required to ensure that method dispatch for ‘is.numeric’ occurs correctly.

Digamos que tengo una lista de data.frames

dflist <- list(data.frame(a=1:3), data.frame(b=10:12, a=4:6))

Si quiero extraer la primera columna de cada elemento de la lista, puedo hacer

lapply(dflist, `[[`, 1) # [[1]] # [1] 1 2 3 # # [[2]] # [1] 10 11 12

¿Por qué no puedo usar la función "$" de la misma manera?

lapply(dflist, `$`, "a") # [[1]] # NULL # # [[2]] # NULL

Pero ambos funcionan:

lapply(dflist, function(x) x$a) `$`(dflist[[1]], "a")

Me doy cuenta de que en este caso uno podría usar

lapply(dflist, `[[`, "a")

pero estaba trabajando con un objeto S4 que no parecía permitir la indexación a través de [[ . Por ejemplo

library(adegenet) data(nancycats) catpop <- genind2genpop(nancycats) mylist <- list(catpop, catpop) #works catpop[[1]]$tab #doesn''t work lapply(mylist, "$", "tab") # Error in slot(x, name) : # no slot of name "..." for this object of class "genpop" #doesn''t work lapply(mylist, "[[", "tab") # Error in FUN(X[[1L]], ...) : this S4 class is not subsettable


Por lo tanto, parece que este problema tiene más que ver con $ y la forma en que normalmente espera nombres sin comillas como el segundo parámetro en lugar de cadenas. Mira este ejemplo

dflist <- list( data.frame(a=1:3, z=31:33), data.frame(b=10:12, a=4:6, z=31:33) ) lapply(dflist, function(x, z) { print(paste("z:",z)); `$`(x,z) }, z="a" )

Vemos los resultados

[1] "z: a" [1] "z: a" [[1]] [1] 31 32 33 [[2]] [1] 31 32 33

por lo que el valor de z se establece en "a", pero $ no está evaluando el segundo parámetro. De modo que devuelve la columna "z" en lugar de la columna "a". Esto lleva a este interesante conjunto de resultados

a<-"z"; `$`(dflist[[1]], a) # [1] 1 2 3 a<-"z"; `$`(dflist[[1]], "z") # [1] 31 32 33 a<-"z"; `$.data.frame`(dflist[[1]], a) # [1] 31 32 33 a<-"z"; `$.data.frame`(dflist[[1]], "z") # [1] 31 32 33

Cuando llamamos $.data.frame directamente estamos evitando el deparsing estándar que ocurre en la primitiva antes del envío (que ocurre cerca de here en la fuente).

La captura agregada con lapply es que pasa argumentos a la función a través del ... mecanismo. Por ejemplo

lapply(dflist, function(x, z) sys.call()) # [[1]] # FUN(X[[2L]], ...) # [[2]] # FUN(X[[2L]], ...)

Esto significa que cuando se invoca $ , desparece el ... en la cadena "..." . Esto explica este comportamiento

dflist<- list(data.frame(a=1:3, "..."=11:13, check.names=F)) lapply(dflist, `$`, "a") # [[1]] # [1] 11 12 13

Lo mismo sucede cuando intentas usar ... tú mismo

f<-function(x,...) `$`(x, ...); f(dflist[[1]], "a"); # [1] 11 12 13 `$`(dflist[[1]], "a") # [1] 1 2 3