Cuando trabajaba, a plyrmenudo me resultaba útil usar adplypara 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 dplyrmá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

mdplyHace 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 individualadplycuando no usas una agrupación? como su función estrechamente integrada se llamagroup_byNOsplit_byRespuestas:
A partir de dplyr 0.2 (creo)
rowwise()se implementa, por lo que la respuesta a este problema se convierte en:No
rowwisealternativaCinco años (!) Más tarde, esta respuesta todavía recibe mucho tráfico. Desde que se le dio,
rowwisecada 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.pmapes 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
plyrydplyrpaquetes, es casi seguro que está utilizando el incorrecto amutatemenos que explícitamente proporcione alcancedplyr::mutate.El enfoque idiomático será crear una función adecuadamente vectorizada.
Rproporcionar lopmaxque es adecuado aquí, sin embargo, también proporcionaVectorizeun contenedor paramapplypermitirle 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
magicPonypaquete que escriba la función por usted.fuente
dplyrforma ... 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 usasdplyrpara eso?magicPonypaquete. LástimaNecesita agrupar por fila:
Esto es lo que
1hicieronadply.fuente
dplyrexperto. 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
adplydesde plyr .Hay dos funciones relacionadas,
by_rowyinvoke_rows.by_rowSegún tengo entendido, lo usa cuando desea recorrer las filas y agregar los resultados al data.frame.invoke_rowsse 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_rowagrega una columna de lista basada en la salida:da:
si en cambio devolvemos a
data.frame, obtenemos una lista condata.frames:da:
La forma en que agregamos la salida de la función está controlada por el
.collatepará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
.rowy el primero no.Finalmente, si nuestra salida es más larga que la longitud 1, ya sea como
vectoro como adata.framecon 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_rowestá 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()deldplyrpaquete.En la
dplyrversió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
purrrversión es la más rápida.fuente
¿Algo como esto?
fuente
dplyrsolució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).dplyroplyrdecirdata.tableque 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.plyrdocumentació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/dplyrcomando para hacer esto.