Cuando trabajaba, a plyr
menudo me resultaba útil usar adply
para funciones escalares que tenía que aplicar a todas y cada una de las filas.
p.ej
data(iris)
library(plyr)
head(
adply(iris, 1, transform , Max.Len= max(Sepal.Length,Petal.Length))
)
Sepal.Length Sepal.Width Petal.Length Petal.Width Species Max.Len
1 5.1 3.5 1.4 0.2 setosa 5.1
2 4.9 3.0 1.4 0.2 setosa 4.9
3 4.7 3.2 1.3 0.2 setosa 4.7
4 4.6 3.1 1.5 0.2 setosa 4.6
5 5.0 3.6 1.4 0.2 setosa 5.0
6 5.4 3.9 1.7 0.4 setosa 5.4
Ahora estoy usando dplyr
más, me pregunto si hay una forma ordenada / natural de hacer esto. Como esto NO es lo que quiero:
library(dplyr)
head(
mutate(iris, Max.Len= max(Sepal.Length,Petal.Length))
)
Sepal.Length Sepal.Width Petal.Length Petal.Width Species Max.Len
1 5.1 3.5 1.4 0.2 setosa 7.9
2 4.9 3.0 1.4 0.2 setosa 7.9
3 4.7 3.2 1.3 0.2 setosa 7.9
4 4.6 3.1 1.5 0.2 setosa 7.9
5 5.0 3.6 1.4 0.2 setosa 7.9
6 5.4 3.9 1.7 0.4 setosa 7.9
mdply
Hace poco pregunté si había un equivalente de in dplyr, y Hadley sugirió que podrían estar preparando algo basado endo
. Supongo que también funcionaría aquí.rowwise()
que se agruparía por cada fila individualadply
cuando no usas una agrupación? como su función estrechamente integrada se llamagroup_by
NOsplit_by
Respuestas:
A partir de dplyr 0.2 (creo)
rowwise()
se implementa, por lo que la respuesta a este problema se convierte en:No
rowwise
alternativaCinco años (!) Más tarde, esta respuesta todavía recibe mucho tráfico. Desde que se le dio,
rowwise
cada vez más no se recomienda, aunque muchas personas parecen encontrarlo intuitivo. Hágase un favor y revise los flujos de trabajo orientados a filas de Jenny Bryan en R con el material tidyverse para obtener un buen manejo de este tema.La forma más directa que he encontrado se basa en uno de los ejemplos de Hadley que usa
pmap
:Con este enfoque, puede dar un número arbitrario de argumentos a la función (
.f
) dentropmap
.pmap
es un buen enfoque conceptual porque refleja el hecho de que cuando estás haciendo operaciones en filas, en realidad estás trabajando con tuplas de una lista de vectores (las columnas en un marco de datos).fuente
plyr
ydplyr
paquetes, es casi seguro que está utilizando el incorrecto amutate
menos que explícitamente proporcione alcancedplyr::mutate
.El enfoque idiomático será crear una función adecuadamente vectorizada.
R
proporcionar lopmax
que es adecuado aquí, sin embargo, también proporcionaVectorize
un contenedor paramapply
permitirle crear una versión arbitraria vectorizada de una función arbitraria.Tenga en cuenta que implementar la vectorización en C / C ++ será más rápido, pero no hay un
magicPony
paquete que escriba la función por usted.fuente
dplyr
forma ... ya que sería más simple sin dplyr, por ejemplowith(df, Coalesce(a,b))
, tal vez, eso es un tipo de respuesta sin embargo, ¿no lo usasdplyr
para eso?magicPony
paquete. LástimaNecesita agrupar por fila:
Esto es lo que
1
hicieronadply
.fuente
dplyr
experto. Esperemos que alguien más venga con algo mejor. Tenga en cuenta que lo limpié un poco con1:n()
.group_by(1:n())
comportamiento. Si nadie tiene otras ideas en la mañana, marcaré las tuyas;)n
: "Esta función se implementa de manera especial para cada fuente de datos y solo se puede usar desde el resumen", aunque parece funcionar.Actualizar 2017-08-03
Después de escribir esto, Hadley cambió algunas cosas nuevamente. Las funciones que solían estar en purrr ahora están en un nuevo paquete mixto llamado purrrlyr , descrito como:
Por lo tanto, deberá instalar + cargar ese paquete para que el siguiente código funcione.
Publicación original
Hadley frecuentemente cambia de opinión acerca de lo que deberíamos usar, pero creo que se supone que debemos cambiar a las funciones en ronroneo para obtener la funcionalidad por fila. Por lo menos, ofrecen la misma funcionalidad y tienen casi la misma interfaz que
adply
desde plyr .Hay dos funciones relacionadas,
by_row
yinvoke_rows
.by_row
Según tengo entendido, lo usa cuando desea recorrer las filas y agregar los resultados al data.frame.invoke_rows
se usa cuando recorre las filas de un data.frame y pasa cada col como argumento a una función. Solo usaremos el primero.Ejemplos
Esto nos permite ver los elementos internos (para que podamos ver lo que estamos haciendo), que es lo mismo que hacerlo
adply
.Por defecto,
by_row
agrega una columna de lista basada en la salida:da:
si en cambio devolvemos a
data.frame
, obtenemos una lista condata.frame
s:da:
La forma en que agregamos la salida de la función está controlada por el
.collate
parámetro. Hay tres opciones: lista, filas, columnas. Cuando nuestra salida tiene longitud 1, no importa si usamos filas o cols.ambos producen:
Si sacamos un data.frame con 1 fila, solo importa un poco lo que usamos:
ambos dan:
excepto que el segundo tiene la columna llamada
.row
y el primero no.Finalmente, si nuestra salida es más larga que la longitud 1, ya sea como
vector
o como adata.frame
con filas, entonces importa si usamos filas o columnas para.collate
:produce, respectivamente:
Entonces, el resultado final. Si desea la
adply(.margins = 1, ...)
funcionalidad, puede usarby_row
.fuente
by_row
está en desuso, al llamarlo dice "usar una combinación de: tidyr :: nest (); dplyr :: mutate (); purrr :: map ()" github.com/hadley/purrrlyr/blob/…Extendiendo la respuesta de BrodieG,
Si la función devuelve más de una fila, entonces, en lugar de
mutate()
,do()
debe usarse. Luego, para combinarlo nuevamente, úselorbind_all()
deldplyr
paquete.En la
dplyr
versióndplyr_0.1.2
, usar1:n()
en lagroup_by()
cláusula no funciona para mí. Esperemos que Hadley lo implementerowwise()
pronto.Probar el rendimiento,
tiene los siguientes resultados:
Esto muestra que la nueva
purrr
versión es la más rápida.fuente
¿Algo como esto?
fuente
dplyr
solución general para cualquier función escalar.wacky.function <- function(col.1, col.2){...}
, y luegoiris.wacky <- wacky.function(iris$Sepal.Length, iris$Petal.Length)
.dplyr
oplyr
decirdata.table
que debes tratar de usar sus expresiones idiomáticas para que tu código no se convierta en una mezcla de estilos difícil de compartir. De ahí la pregunta.plyr
documentación es "plyr es un conjunto de herramientas que resuelve un conjunto común de problemas: necesita dividir un gran problema en partes manejables, operar en cada pieza y luego volver a unir todas las piezas". Este parece ser un problema muy diferente para el cual las operaciones de columnas elementales son la mejor herramienta. Esto también podría explicar por qué no hay "natural"plyr
/dplyr
comando para hacer esto.