Esta publicación ofrece una breve revisión de la función agregada utilizada para los datos.enmarca y presenta algunos usos interesantes: desde los triviales pero prácticos hasta los problemas más complicados que he resuelto con aggregate.
Aggregate
es una función en base R que puede, como su nombre indica, agregar el data.frame
d.f introducido aplicando una función especificada por el parámetro FUN
a cada columna de subdatos.fotogramas definidos por el parámetro de entrada by
.
El parámetro by
tiene que ser list
. Sin embargo, dado que data.frame
se manejan como listas de columnas (con nombre), una o más columnas de un data.frame
también se pueden pasar como parámetro by
. Curiosamente, si estas columnas son de la misma data.frame
que la introducida como x
, esas columnas no se pasan a la función FUN
.
La función a aplicar tiene que ser capaz de aceptar un vector
(ya que se llamará con partes de una columna de un data.frame
como entrada).
Los subdatos.los fotogramas definidos por el parámetro de entrada by
se pueden considerar como indexación lógica:
d.f <- data.frame(rating = c("AAA", "A", "A", "AAA", "BB", "BB", "AAA", "A"))i <- 1by <- d.f$ratingsub.data.frame <- d.f, ]
y haga esto para cada i
entre 1 y length(unique(by))
. Tenga en cuenta que la variable by
no tiene que coincidir con una (o más) columna de data.frame
, pero podría ser cualquier cosa. Por lo tanto, se puede reproducir la funcionalidad aggregate
mediante un ciclo for
que ejecuta la variable de ciclo sobre los valores únicos de la variable pasada como by
y un sapply
aplicando la función pasada como FUN
a cada columna de la sub data.frame
.datos.marco. Sin embargo, una solución alternativa de este tipo sería muy difícil de documentar, ya que no estaría claro qué (y por qué) está haciendo realmente este código.
Aggregate
siempre devuelve un data.frame
como resultado. Este data.frame
contendrá los valores (ahora únicos) del parámetro de entrada by
como primera columna y luego columnas que contengan los resultados de la llamada a la función en el parámetro FUN
aplicado a las partes de las columnas del data.frame
introducido. Es interesante notar que si la función FUN
devuelve múltiples valores, la clase de las columnas del resultado data.frame
será list
o algo a lo que se puede convertir list
(vea el último ejemplo a continuación).
Es importante tener en cuenta que la llamada a función se aplica a vectores sin nombre en lugar de columnas con nombre de un data.frame
y, por lo tanto, referirse a los nombres de data.frame
no funcionará, ni tampoco las referencias a columnas como s.d.f
.
Ejemplos básicos
Los usos más básicos de aggregate implican funciones básicas como mean
y sd
. De hecho, es uno de los usos más comunes de aggregate
para comparar la media u otras propiedades de los grupos de muestra.
Recientemente reproduje cálculos de una hoja de Excel. La mayoría de las fórmulas eran subtotales y totales generales. La hoja de Excel no estaba muy bien organizada para este propósito: se utilizaron sumas sobre filas, columnas y totales de esas sumas. En R, he cambiado los datos a una representación de esquema de estrella (cuando todos los metadatos se representan por fila y cada valor obtiene su propia fila) usando reshape2
paquete y melt
luego usé aggregate
a lo largo de diferentes variables para obtener los diferentes totales. Cuantas menos variables use en by
, más agregado será el resultado final: el total general a lo largo de una dimensión simplemente usa esa dimensión como «by», mientras que los subtotales se pueden lograr usando múltiples variables como by
. El FUN
en este caso fue, por supuesto, sum
.
Un uso práctico de aggregate y una función base es obtener el número de apariciones de los diversos valores:
Mi uso favorito de aggregate con una función base es obtener el último día de cada mes en una serie de fechas. Para hacerlo, se puede usar el siguiente código (suponiendo que sus fechas se almacenen en un formato «AAAA-MM-DD» como cadenas o como Date
):
Esto fue muy útil cuando se trabaja con información bancaria, donde el último día del mes dependía de días festivos bancarios y fines de semana.
Usos avanzados
Los usos más avanzados de aggregate
dependen de escribir su propio function
, por ejemplo, funciones anónimas pasadas como parámetro FUN
. Para ello, se puede utilizar la sintaxis
# do not run the syntaxaggregate(x = d.f, by = by.list, FUN = function(s.d.f){y <- s.d.f; return(y)}
Los usos posibles van desde llamar a métricas de riesgo de cartera complejas para los grupos de riesgo homogéneos de una cartera hasta ajustar una distribución a categorías de muestras a cualquier cosa que pueda imaginar, realmente.
Este es un ejemplo con una métrica de riesgo de cartera» compleja » (exposición a diferentes contrapartes en diferentes clases de activos):
Aquí está el uso de la función aggregate()
.
A continuación: ajuste de una distribución gaussiana a observaciones por categorías:
A continuación utilizamos la función aggregate()
para encontrar la media y la desviación estándar por categorías.
Este último ejemplo muestra varias propiedades interesantes. En primer lugar, las variables data.frame
a aggregate
y la lista de variables by
no tienen que ser las mismas. Si bien esto está implícito en otros lugares de la publicación, este es un ejemplo explícito de tal configuración. En segundo lugar, la función pasada como FUN
no es solo una función anónima, sino que se extrae de una función con más de un parámetro de entrada. Se ha creado una función de una sola variable de entrada observations
a partir de la función de dos variables de entrada fitdistr
: se fija una de las variables de entrada estableciendo densfun = "normal"
. En tercer lugar, en lugar de devolver el valor de retorno completo de la función fitdistr
, el valor de retorno está restringido al elemento estimate
del valor de retorno. Y por último, pero no menos importante, el valor de retorno de la función anónima pasada a FUN
consta de dos variables y no solo una. Curiosamente, aggregate arroja el valor de retorno de list
a matrix
y nombra los elementos por nosotros. Sin embargo, estos nombres no se pueden usar para hacer referencia a las columnas de la matriz. Sin embargo, puede hacer referencia a ellos de la siguiente manera:
distr.estimate$observation] 3.016988
Palabras de cierre
Espero que haya encontrado útil lo anterior. Ahora que está más familiarizado con aggregate
, es hora de la verdad: todo lo anterior y mucho más se puede hacer con data.table
, y con un rendimiento mucho más rápido. Sin embargo, data.table
tiene una sintaxis compleja y uno realmente tiene que entender cómo funcionan las cosas bajo el capó, mientras que aggregate
es simple y perspicaz. Hasta que se sienta cómodo con la lógica de agregación y la sintaxis de data.table
, es una inversión digna escribir primero el código usando aggregate
y luego optimizarlo reescribiéndolo usando data.table
.
Para aquellos de ustedes que estén interesados, llegará una publicación dedicada donde lo anterior se rehace con data.table
, junto con algunos casos de uso adicionales específicos de data.table
.