div - La iteración en fila como aplicar con purrr
sidebarpanel shiny (3)
¿Cómo puedo lograr la iteración en filas usando purrr :: map?
Así es como lo haría con una aplicación de fila estándar.
df <- data.frame(a = 1:10, b = 11:20, c = 21:30)
lst_result <- apply(df, 1, function(x){
var1 <- (x[[''a'']] + x[[''b'']])
var2 <- x[[''c'']]/2
return(data.frame(var1 = var1, var2 = var2))
})
Sin embargo, esto no es demasiado elegante, y preferiría hacerlo con purrr. Puede (o no) ser más rápido, también.
Puedes usar pmap
para la pmap
por filas. Las columnas se utilizan como argumentos de cualquier función que esté utilizando. En tu ejemplo tendrías una función de tres argumentos.
Por ejemplo, aquí está pmap
usando una función anónima para el trabajo que está haciendo. Las columnas se pasan a la función en el orden en que están en el conjunto de datos.
pmap(df, function(a, b, c) {
data.frame(var1 = a + b,
var2 = c/2)
} )
Puede usar la "mano corta" de la tilde purrr para una función anónima haciendo referencia a las columnas en orden con números precedidos por dos puntos.
pmap(df, ~data.frame(var1 = ..1 + ..2,
var2 = ..3/2) )
Si desea obtener estos resultados particulares como un cuadro de datos en lugar de una lista, puede usar pmap_dfr
.
Tenga en cuenta que solo está utilizando operaciones vectorizadas en su ejemplo, por lo que podría hacer muy bien:
df %>% dplyr::transmute(var1 = a+b,var2 = c/2)
(o en la base R: transform(df,var1 = a+b,var2 = c/2)[4:5]
)
Si usa funciones no vectorizadas como la mediana, puede usar pmap
como en la respuesta de dplyr::rowwise
, o usar dplyr::rowwise
.
rowwise
es más lento y los mantenedores de paquetes aconsejan utilizar la familia de map
lugar, pero en algunos casos es más fácil de pmap
que pmap
. Personalmente todavía lo uso cuando la velocidad no es un problema:
library(dplyr)
df %>% transmute(var3 = pmap(.,~median(c(..1,..2,..3))))
df %>% rowwise %>% transmute(var3 = median(c(a,b,c)))
(para volver a una salida de lista sin nombre estricta: res %>% split(seq(nrow(.))) %>% unname
)
Usted es libre de hacer siempre una envoltura alrededor de una función que "le guste".
rmap <- function (.x, .f, ...) {
if(is.null(dim(.x))) stop("dim(X) must have a positive length")
.x <- t(.x) %>% as.data.frame(.,stringsAsFactors=F)
purrr::map(.x=.x,.f=.f,...)
}
Aplicar la nueva función rmap
( r owwise map ).
rmap(df1,~{
var1 <- (.x[[1]] + .x[[2]])
var2 <- .x[[3]]/2
return(data.frame(var1 = var1, var2 = var2))
})
Información adicional: (eval de arriba a abajo)
df1 <- data.frame(a=1:3,b=1:3,c=1:3)
m <- matrix(1:9,ncol=3)
apply(df1,1,sum)
rmap(df1,sum)
apply(m,1,sum)
rmap(m,sum)
apply(1:10,1,sum) # intentionally throws an error
rmap(1:10,sum) # intentionally throws an error