Data.table: funciones rodantes, agregados rodantes, ventana deslizante, media móvil

Creado en 21 abr. 2018  ·  39Comentarios  ·  Fuente: Rdatatable/data.table

Para recopilar los requisitos en un solo lugar y actualizar discusiones de ~ 4 años que crearon este problema para cubrir la función de _ funciones rodantes_ (también conocida como _ agregados rodantes_, _ ventana deslizante_ o _ promedio móvil _ / _ agregados móviles_).

funciones rodantes

  • [x] rollmean
  • [x] rollsum
  • [] rollmin
  • [] rollmax
  • [] rollmedian
  • [] rollprod
  • [] rollsd
  • [] rollvar
  • [] rollrank
  • [x] rollapply (DIVERSIÓN proporcionada por el usuario)
  • [] rollregression (muy demandado)
  • [] rollcor?
  • [] rollcov?

características

  • [x] varias columnas a la vez
  • [x] varias ventanas a la vez
  • [x] varias columnas y varias ventanas a la vez
  • [x] entrada de vectores atómicos y ventana única devuelve vectores atómicos
  • [x] lista de vectores de varias longitudes
  • [x] alinear: izquierda / centro / derecha
  • [x] manejando NA
  • [x] constante de relleno
  • [x] compatibilidad con vectores largos
  • [] soporte de ventana parcial (si es necesario, se puede encontrar en ea766f2499034cedf6abf872440268b78979147c)
  • [x] compatibilidad con ventanas adaptables
  • [x] usa openmp para paralelizar el cálculo de múltiples columnas / ventanas
  • [x] corrección de error de redondeo
  • [x] sincronización en modo detallado desde la región paralela (bloqueado por ~ # 3422 ~, # 3423)
feature request

Comentario más útil

@mattdowle respondiendo preguntas de relaciones públicas

¿Por qué estamos haciendo esto dentro de data.table? ¿Por qué lo estamos integrando en lugar de contribuir a los paquetes existentes y usarlos desde data.table?

  1. Se crearon 3 problemas diferentes al solicitar esa funcionalidad en data.table. También múltiples preguntas SO etiquetadas como data.table. Los usuarios esperan que esté dentro del alcance de data.table.
  2. data.table se adapta perfectamente a los datos de series de tiempo y los agregados móviles son estadísticas bastante útiles allí.

mi conjetura es que se reduce a la sintaxis (características solo posibles o convenientes si están integradas en data.table; por ejemplo, [...] dentro y optimizado) y la construcción de elementos internos de data.table en la función rodante en el nivel C; por ejemplo, froll * debe ser consciente y utilizar índices y claves de data.table. Si es así, se necesitan más detalles al respecto; por ejemplo, un ejemplo breve y sencillo.

Para mí personalmente se trata de velocidad y falta de cadena de dependencias, hoy en día no es fácil de conseguir.
Los índices / clave podrían ser útiles para frollmin / frollmax, pero es poco probable que el usuario cree un índice en la variable de medida. Es poco probable que el usuario haga una variable de índice en la medida, además, aún no hemos realizado esta optimización para mínimo / máximo. No veo mucho sentido para la optimización de GForce porque la memoria asignada no se libera después de pasar lista * sino que se devuelve como respuesta (a diferencia de la media, suma, etc.).

Si no hay un argumento convincente para la integración, entonces deberíamos contribuir con los otros paquetes.

Enumeré algunos arriba, si no está convencido, le recomiendo que complete una pregunta a los usuarios de data.table, pregunte en twitter, etc. para verificar la respuesta. Esta función fue solicitada durante mucho tiempo y por muchos usuarios. Si la respuesta no lo convence, puede cerrar este problema.

Todos 39 comentarios

Implementación rollmean , simplificada.

x = data.table(v1=1:5, v2=1:5)
k = c(2, 3)
i - single column
j - single window
m - int referring to single row
w - current row's sum of rolling window
r - answer for each i, j



md5-be70673ef4a3bb883d4f334bd8fadec9



for i in x
  for j in k
  r = NA_real_
  w = 0
    for m in 1:length(i)
      w = w + i[m]
      w = w - i[m-j]
      r[m] = w / j

sí, y muchas más funciones enrolladas siguen la misma idea básica (incluyendo
Desviación estándar rodante / cualquier momento basado en expectativas y cualquier función
como rollproduct que usa invertible * en lugar de + para agregar dentro
la ventana

Siempre imaginé la funcionalidad de la ventana rodante como agrupar el conjunto de datos en varios grupos superpuestos (ventanas). Entonces la API se vería así:

DT[i, j,
   by = roll(width=5, align="center")]

Entonces, si j contiene, digamos, mean(A) , podemos reemplazarlo internamente con rollmean(A) , exactamente como lo estamos haciendo con gmean() este momento. O j puede contener una funcionalidad arbitrariamente complicada (digamos, ejecutar una regresión para cada ventana), en cuyo caso le suministraríamos .SD data.table, exactamente como lo hacemos con los grupos ahora.

De esta manera, no es necesario introducir más de 10 funciones nuevas, solo una. Y se siente data.table-y en espíritu también.

si de acuerdo

El sábado 21 de abril de 2018 a las 3:38 p.m. Pasha Stetsenko [email protected]
escribió:

Siempre imaginé la funcionalidad de la ventana rodante como agrupar los
conjunto de datos en varios grupos superpuestos (ventanas). Entonces la API miraría
algo como esto:

DT [i, j,
por = rollo (ancho = 5, alinear = "centro")]

Entonces, si j contiene, digamos, mean (A), podemos reemplazarlo internamente con
rollmean (A) - exactamente como lo estamos haciendo con gmean () en este momento. O puedo
contienen una funcionalidad arbitrariamente complicada (digamos, ejecute una regresión para
cada ventana), en cuyo caso le suministraríamos la tabla de datos .SD, exactamente
como lo hacemos con los grupos en este momento.

De esta manera, no es necesario introducir más de 10 funciones nuevas, solo una. Y es
se siente data.table-y en espíritu también.

-
Estás recibiendo esto porque hiciste un comentario.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/Rdatatable/data.table/issues/2778#issuecomment-383275134 ,
o silenciar el hilo
https://github.com/notifications/unsubscribe-auth/AHQQdbADiE4aAI1qPxPnFXUM5gR-0w2Tks5tquH8gaJpZM4TeTQf
.

@ st-pasha idea interesante, parece data.table-y spirit, pero impondrá muchas limitaciones y no es realmente apropiado para esta categoría de funciones.


  • cómo realizar rollmean por grupo
DT[, rollmean(V1, 3), by=V2]
  • cómo calcular diferentes tamaños de ventana para diferentes columnas
DT[, .(rollmean(V1, 3), rollmean(V2, 100))]
  • cómo calcular rollmean fuera de [.data.table como ahora permitimos el turno
rollmean(rnorm(10), 3)
  • cómo admitir consultas como
DT[, .(rollmean(list(V1, V2), c(5, 20)), rollmean(list(V2, V3), c(10, 30)))]
  • cómo llamar mean y rollmean en la misma llamada j
DT[, .(rollmean(V1, 3), mean(V1)), by=V2]

Por lo general, cuando usamos by , agregamos datos a un número menor de filas, mientras que las funciones móviles siempre devuelven un vector de la misma longitud que la entrada. Este tipo de funciones en SQL tienen API en el siguiente estilo:

SELECT AVG(value) OVER (ROWS BETWEEN 99 PRECEDING AND CURRENT ROW)
FROM tablename;

Aún puede combinarlo con GROUP BY de la siguiente manera:

SELECT AVG(value) OVER (ROWS BETWEEN 99 PRECEDING AND CURRENT ROW)
FROM tablename
GROUP BY group_columns;

Entonces, en SQL, esas funciones permanecen en SELECT que se refiere a j en DT.
En DT podríamos conseguir lo mismo con:

DT[, rollmean(value, 100)]
DT[, rollmean(value, 100), group_columns]

Las funciones sucesivas encajan en la misma categoría de funciones que shift que también devuelve el mismo número de filas que obtuvo en la entrada.
Shift en SQL se ve así:

SELECT LAG(value, 1) OVER ()
FROM tablename;

mean y rollmean no son solo funciones diferentes, son categorías de funciones diferentes. Uno pretendía agregar según el grupo, otro no agregar en absoluto. Esto es fácilmente visible en SQL donde no usamos GROUP BY para el tipo de funciones sucesivas, pero necesitamos usar GROUP BY para agregados como mean (eventualmente obteniendo el total de la subvención al agrupar cláusula no está presente).
No veo un razonamiento sólido para tratar de aplicar las mismas reglas de optimización que lo hacemos para mean , especialmente cuando realmente no se ajusta al caso de uso, y todo eso solo por el bien de los datos.table-y espíritu. La propuesta actual también es data.table-y spirit, que se puede combinar fácilmente con := , igual que shift . Simplemente agrega un conjunto de nuevas funciones, actualmente no disponibles en data.table.

@jangorecki Gracias, todas estas son consideraciones válidas. Por supuesto, diferentes personas tienen diferentes experiencias y diferentes puntos de vista sobre lo que debería considerarse "natural".

Es posible realizar rollmean por grupo: esto es solo una agrupación de 2 niveles: DT[, mean(V1), by=.(V2, roll(3))] . Sin embargo, no veo cómo hacer diferentes tamaños de ventana en diferentes columnas con mi sintaxis ...

Debo admitir que nunca antes había visto la sintaxis SQL para uniones rodantes. Es interesante que usen un agregador estándar como AVG pero le apliquen la especificación de ventanas. En cuanto a la documentación de Transact-SQL, hay algunas ideas interesantes, por ejemplo, la distinción entre selección de fila lógica / física. Permiten diferentes operadores "OVER" en diferentes columnas, sin embargo, en todos los ejemplos que dan, es la misma cláusula OVER repetida varias veces. Por lo tanto, sugiere que este caso de uso es mucho más común y, por lo tanto, usar un solo grupo roll() resultaría en menos repetición.

Además, esta pregunta SO proporciona una idea interesante de por qué se introdujo la sintaxis OVER en SQL:

Puede utilizar GROUP BY SalesOrderID. La diferencia es que con GROUP BY solo puede tener los valores agregados para las columnas que no están incluidas en GROUP BY. Por el contrario, al usar funciones agregadas con ventana en lugar de GROUP BY, puede recuperar valores agregados y no agregados. Es decir, aunque no está haciendo eso en su consulta de ejemplo, puede recuperar tanto los valores de OrderQty individuales como sus sumas, recuentos, promedios, etc., en grupos de los mismos SalesOrderID.

Entonces, parece que la sintaxis está diseñada para eludir la limitación del SQL estándar donde los resultados agrupados no se pueden combinar con valores no agregados (es decir, seleccionando A y mean(A) en la misma expresión). Sin embargo, data.table no tiene tal limitación, por lo que tiene más libertad en la elección de la sintaxis.


Ahora bien, si realmente queremos adelantarnos a la curva, debemos pensar en una perspectiva más amplia: cuáles son las funciones "rodantes", para qué se usan, cómo se pueden extender, etc. Aquí está mi opinión. desde el punto de vista de un estadístico:

La función "Media rodante" se utiliza para suavizar algunas entradas ruidosas. Digamos, si tiene observaciones a lo largo del tiempo y quiere tener alguna noción de "cantidad promedio", que sin embargo variaría con el tiempo, aunque muy lentamente. En este caso, se puede considerar la "media móvil de las últimas 100 observaciones" o la "media móvil de todas las observaciones anteriores". De manera similar, si observa cierta cantidad en un rango de entradas, puede suavizarla aplicando "media móvil sobre ± 50 observaciones".

  • Entonces, la primera extensión es mirar "ventanas suaves": imagine una media sobre las observaciones pasadas donde cuanto más una observación en el pasado es, menor es su contribución. O un promedio de observaciones cercanas sobre un núcleo gaussiano.
  • En segundo lugar están las ventanas adaptativas. Por ejemplo, si tiene una entrada ruidosa definida en un intervalo [0, 1], suavizarla usando una ventana ± N produce un resultado sesgado cerca de los bordes. Un estimador insesgado adaptaría la forma de la ventana en función de la distancia desde el borde.
  • Suavizado de remuestreo: la restricción de producir exactamente tantas observaciones como en los datos de origen es demasiado limitante. Si piensa en sus datos como observaciones ruidosas de alguna función subyacente, entonces es perfectamente razonable pedir que se calculen los valores suavizados de esa función en una malla que sea más gruesa / fina que la entrada original. O quizás los datos originales están espaciados irregularmente y desea volver a muestrearlos en una cuadrícula regular.
  • Jackknife: para cada observación desea calcular el promedio / regresión de todas las observaciones excepto la actual.
  • División de K-fold: vea los datos como varios grupos donde cada grupo excluye solo una pequeña parte de las observaciones.

Todos estos se pueden implementar como operadores de agrupación extendidos, siendo las ventanas móviles solo uno de los elementos de esta lista. Dicho esto, no entiendo por qué no podemos tener las dos cosas.

Debo admitir que nunca antes había visto la sintaxis SQL para uniones rodantes.

Supongo que te refieres a funciones rodantes, el problema no tiene nada que ver con las combinaciones rodantes.

Permiten diferentes operadores "OVER" en diferentes columnas, sin embargo, en todos los ejemplos que dan, es la misma cláusula OVER repetida varias veces. Por lo tanto, sugiere que este caso de uso es mucho más común y, por lo tanto, usar un solo grupo roll () resultaría en menos repetición.

Es solo una cuestión de caso de uso, si está llamando al mismo OVER () muchas veces, puede que le resulte más eficaz usar GROUP BY , crear una tabla de búsqueda y reutilizarla en otras consultas. Independientemente de los ejemplos que haya, se requiere repetir OVER () para retener la característica de localidad para cada medida proporcionada. Mis casos de uso de Data Warehouses no eran tan simples como los de Microsoft docs.

Por el contrario, al usar funciones agregadas con ventana en lugar de GROUP BY, puede recuperar valores agregados y no agregados.

En data.table hacemos := y by en una consulta para lograrlo.

Por lo tanto, parece que la sintaxis está diseñada para eludir la limitación del SQL estándar donde los resultados agrupados no se pueden combinar con valores no agregados (es decir, seleccionar tanto A como la media (A) en la misma expresión). Sin embargo, data.table no tiene tal limitación, por lo que tiene más libertad en la elección de la sintaxis.

No es una gran limitación de SQL, sino solo el diseño de GROUP BY, que se agregará, de la misma manera que nuestros agregados by . Se requirió una nueva API para cubrir las nuevas funcionalidades de la ventana. La agrupación para la función de ventana SQL se puede proporcionar para cada llamada de función usando FUN() OVER (PARTITION BY ...) donde _partición por_ es como agrupación local para medida única. Entonces, para lograr la flexibilidad de SQL, necesitaríamos usar j = mean(V1, roll=5) o j = over(mean(V1), roll=5) manteniendo esa API en j . Aún así, este enfoque no permitirá admitir todos los casos de uso mencionados anteriormente.

puede suavizarlo aplicando "media móvil sobre ± 50 observaciones".

Esto es para lo que se usa el argumento align .

Entonces, la primera extensión es mirar "ventanas suaves": imagine una media sobre las observaciones pasadas donde cuanto más una observación en el pasado es, menor es su contribución. O un promedio de observaciones cercanas sobre un núcleo gaussiano.

Hay muchas variantes (número virtualmente ilimitado) de promedios móviles, la función de ventana de suavizado más común (que no sea rollmean / SMA) es la media móvil exponencial (EMA). No es trivial decidir cuál debe incluirse y cuál no, y en realidad es mejor tomar esa decisión de acuerdo con las solicitudes de funciones que vendrán de los usuarios, hasta ahora no se solicitó ninguna como esta.

Todos estos se pueden implementar como operadores de agrupación extendidos, siendo las ventanas móviles solo uno de los elementos de esta lista.

Seguramente pueden, pero si observa SO y los problemas creados en nuestro repositorio, verá que esas pocas funciones móviles aquí son responsables del 95 +% de las solicitudes de los usuarios. Estoy feliz de trabajar en EMA y otros MA (aunque no estoy seguro de si data.table es el mejor lugar para ellos), pero como un tema separado. Algunos usuarios, incluido yo, están esperando un promedio móvil simple en data.table desde hace 4 años.

Aquí está mi opinión, desde el punto de vista de un estadístico.

Mi punto de vista proviene del almacenamiento de datos (donde utilicé la función de ventana, al menos una vez a la semana) y el análisis de tendencias de precios (donde utilicé decenas de promedios móviles diferentes).

rollmean borrador de roll . Encontré que la mayoría de los otros paquetes que implementan medias móviles no pueden manejar bien con na.rm=FALSE y NA presentes en la entrada. Esta implementación maneja NA de manera consistente a mean , lo que impone una sobrecarga adicional debido a las llamadas ISNAN . Podríamos permitir una versión más rápida pero menos segura de la API si el usuario está seguro de que no hay NA en la entrada.
PR está en el n. ° 2795

@mattdowle respondiendo preguntas de relaciones públicas

¿Por qué estamos haciendo esto dentro de data.table? ¿Por qué lo estamos integrando en lugar de contribuir a los paquetes existentes y usarlos desde data.table?

  1. Se crearon 3 problemas diferentes al solicitar esa funcionalidad en data.table. También múltiples preguntas SO etiquetadas como data.table. Los usuarios esperan que esté dentro del alcance de data.table.
  2. data.table se adapta perfectamente a los datos de series de tiempo y los agregados móviles son estadísticas bastante útiles allí.

mi conjetura es que se reduce a la sintaxis (características solo posibles o convenientes si están integradas en data.table; por ejemplo, [...] dentro y optimizado) y la construcción de elementos internos de data.table en la función rodante en el nivel C; por ejemplo, froll * debe ser consciente y utilizar índices y claves de data.table. Si es así, se necesitan más detalles al respecto; por ejemplo, un ejemplo breve y sencillo.

Para mí personalmente se trata de velocidad y falta de cadena de dependencias, hoy en día no es fácil de conseguir.
Los índices / clave podrían ser útiles para frollmin / frollmax, pero es poco probable que el usuario cree un índice en la variable de medida. Es poco probable que el usuario haga una variable de índice en la medida, además, aún no hemos realizado esta optimización para mínimo / máximo. No veo mucho sentido para la optimización de GForce porque la memoria asignada no se libera después de pasar lista * sino que se devuelve como respuesta (a diferencia de la media, suma, etc.).

Si no hay un argumento convincente para la integración, entonces deberíamos contribuir con los otros paquetes.

Enumeré algunos arriba, si no está convencido, le recomiendo que complete una pregunta a los usuarios de data.table, pregunte en twitter, etc. para verificar la respuesta. Esta función fue solicitada durante mucho tiempo y por muchos usuarios. Si la respuesta no lo convence, puede cerrar este problema.

Encontré que sparklyr puede admitir funciones rodantes muy bien en un conjunto de datos a gran escala.

@harryprince podría poner un poco más de luz al proporcionar un código de ejemplo de cómo lo haces en sparklyr.
Según la viñeta dplyr de "Funciones de ventana"

Los agregados rodantes operan en una ventana de ancho fijo. No los encontrará en base R o en dplyr, pero hay muchas implementaciones en otros paquetes, como RcppRoll.

AFAIU, utiliza una API de chispa personalizada a través de Sparklyr para la que no se implementa la interfaz dplyr, ¿correcto?

Este problema se trata de agregados móviles, otros "tipos" de funciones de ventana ya están en data.table durante mucho tiempo.

También sería útil proporcionar un ejemplo para que podamos comparar el rendimiento (en memoria) con el de sparklyr / SparkR .

Se me acaba de ocurrir que esta pregunta:

¿Cómo calcular diferentes tamaños de ventana para diferentes columnas?

tiene, de hecho, un alcance más amplio y no se aplica únicamente a las funciones sucesivas.

Por ejemplo, parece perfectamente razonable preguntar cómo seleccionar el precio promedio del producto por fecha, luego por semana, y luego quizás por semana + categoría, todo dentro de la misma consulta. Si alguna vez implementamos dicha funcionalidad, la sintaxis natural para ella podría ser

DT[, .( mean(price, by=date), 
        mean(price, by=week), 
        mean(price, by=c(week, category)) )]

Ahora, si esta funcionalidad ya estuviera implementada, entonces habría sido un simple salto desde allí a los medios rodantes:

DT[, .( mean(price, roll=5), 
        mean(price, roll=20), 
        mean(price, roll=100) )]

No digo que esto sea inequívocamente mejor que rollmean(price, 5) , simplemente agregando algunas alternativas para considerar ...

@ st-pasha

cómo seleccionar el precio promedio del producto por fecha, luego por semana, y luego quizás por semana + categoría, todo dentro de la misma consulta.

AFAIU, esto ya es posible usando ?groupingsets , pero aún no está vinculado a [.data.table .

@jangorecki , @ st-pasha, and Co. - ¡Gracias por todo su trabajo en esto! Tengo curiosidad por saber por qué se eliminó el soporte de ventana parcial del alcance, ¿existe alguna posibilidad de que esa funcionalidad vuelva a la hoja de ruta? Sería útil para mí a veces y llenaría un vacío de funcionalidad que, hasta donde yo sé, no se ha llenado ni en zoo ni en RcppRoll .

Esta pregunta de desbordamiento de pila es un buen ejemplo de una aplicación móvil que podría beneficiarse de un argumento partial = TRUE .

@msummersgill Gracias por sus comentarios. En la primera publicación, vinculé explícitamente el compromiso sha donde se puede encontrar el código de característica de ventana parcial. La implementación que está allí se eliminó más tarde para reducir la complejidad del código. También imponía un bajo costo de rendimiento incluso cuando no se usaba esa función. Esta característica puede (y probablemente debería) implementarse de otra manera, primero complete como está, y luego simplemente complete la ventana parcial que falta usando un bucle adicional de 1:window_size . Entonces, la sobrecarga de esa función solo se nota cuando la usa. Sin embargo, proporcionamos esa funcionalidad a través del argumento adaptive , donde la función partial es solo un caso especial de la media móvil adaptive . Hay un ejemplo de cómo lograr partial usando adaptive en ?froll manual . Pegándolo aquí:

d = as.data.table(list(1:6/2, 3:8/4))
an = function(n, len) c(seq.int(n), rep(n, len-n))
n = an(3, nrow(d))
frollmean(d, n, adaptive=TRUE)

Por supuesto, no será tan eficiente como la función de balanceo no adaptativa usando un bucle adicional para llenar solo una ventana parcial.
AFAIK zoo tiene la función partial .

¿Tienen algún plan para agregar funciones de regresión continua a data.table?

@waynelapierre, si habrá demanda para eso, entonces sí. Tienes mi +1

gracias esto es genial. Sin embargo, solo una pregunta. Solo veo agregados móviles simples, como una media móvil o una mediana móvil. ¿También está implementando funciones rodantes más refinadas, como marcos de datos DT rodantes? Digamos, cree un DT rodante usando las últimas 10 obs y ejecute una regresión lm en él.

¡Gracias!

@randomgambit Yo diría que está fuera de alcance, a menos que haya una gran demanda para eso. No sería muy difícil hacerlo para ser más rápido que el R / zoo base simplemente manejando el bucle anidado en C. Pero deberíamos intentar implementarlo usando el algoritmo "en línea", para evitar el bucle anidado. Esto es más complicado y eventualmente podríamos hacerlo para cualquier estadística, por lo que tenemos que cortar esas estadísticas en algún momento.

@jangorecki interesante gracias. Eso significa que seguiré usando tsibble para incrustar ... DATA.TABLES en un tibble ! mente asombrada: D

Intenté usar frollmean para calcular una "curva logística" no paramétrica que muestra P[y | x] para y binarios usando los vecinos más cercanos de x . Me sorprendió que y almacenado como logical no se enviara automáticamente a integer :

DT = data.table(x = rnorm(1000), y = runif(1000) > .5)
DT[order(x), .(x, p_y = frollmean(y, 50L))]

Error en froll (fun = "mean", x = x, n = n, fill = fill, algo = algo, align = align,:
x debe ser de tipo numérico

Un ejemplo de cómo los argumentos vectorizados x / n pueden afectar el rendimiento.
https://github.com/AdrianAntico/RemixAutoML/commit/d8370712591323be01d0c66f34a70040e2867636#r34784427
menos bucles, código más fácil de leer, mucho más rápido (aceleración 10x-36x).

frollapply listo: https://github.com/Rdatatable/data.table/pull/3600

    ### fun             mean     sum  median
    # rollfun          8.815   5.151  60.175
    # zoo::rollapply  34.373  27.837  88.552
    # zoo::roll[fun]   0.215   0.185      NA
    # frollapply       5.404   1.419  56.475
    # froll[fun]       0.003   0.002      NA

hola chicos, DIVERSIÓN (definida por el usuario) pasada a frollapply se cambiará para devolver un objeto R o data.frame (data.table), x pasada a frollapply podría ser data.table de carácter no forzado a numérico, entonces FUN podría funcionar en etiquetas y frollapply devuelven una lista? luego podemos hacer una regresión progresiva o pruebas continuas como hacer las pruebas de Benford o el resumen en las etiquetas.

Siempre es útil proporcionar un ejemplo reproducible. Para aclarar ... en tal escenario, le gustaría frollapply(dt, 3, FUN) devolver una lista de longitud nrow(dt) donde cada elemento de la lista será data.table devuelto por FUN(dt[window]) ?
frollapply(x=dt, n=3, fun=FUN)[[3]] es igual a FUN(dt[1:3])
frollapply(x=dt, n=3, FUN=FUN)[[4]] es igual a FUN(dt[2:4])
¿Es eso correcto? @ jerryfuyu0104

Actualmente admitimos varias columnas pasadas al primer argumento, pero las procesamos por separado, en bucle. Probablemente necesitemos un argumento adicional multi.var=FALSE , cuando se establece en verdadero, no se repite x (como lo hace ahora: list(FUN(x[[1]]),FUN(x[[2]])) ) sino que pasa todas las columnas FUN(x) .

alguna actualización para esto?

Secundo esa solicitud anterior.

Además, ¿sería posible admitir un argumento "parcial" para permitir ventanas parciales?

@eliocamp, ¿ podrías explicarnos qué es una ventana partial ?

@eliocamp sería posible apoyar el argumento "parcial". Es posible que ya lo sepa, pero el soporte para esta funcionalidad ya existe, usando el argumento adaptive=TRUE , vea los ejemplos para obtener más detalles.

Significaría calcular la función desde el principio hasta el final en lugar de formar el punto de media ventana.
Por ejemplo, para una media móvil de 11 de ancho, el primer elemento devuelto sería la media de los elementos del 1 al 6. El segundo, la media del 1 al 7, y así sucesivamente.

@jangorecki oh, gracias, ¡no sabía eso! Lo comprobaré.

De acuerdo, necesitamos un argumento parcial, no solo por conveniencia sino también por velocidad. adaptive=TRUE agrega una sobrecarga.
Y sí, también necesitamos una regresión progresiva, por lo que debemos suministrar múltiples variables y aplicarlas a la vez, no cada una por separado.
No hay ninguna actualización sobre el estado de esos.

Me encantaría ayudar, pero mis habilidades en C ++ son absolutamente inexistentes. : sweat: ¿Crees que podría ser adecuado para novatos?

No codificamos en C ++ sino en C. Sí, es un buen lugar para empezar. Hice exactamente eso en frollmean.

Miro el código y parece abrumador. Pero te actualizaré en cualquier caso.

Pero ahora, para otra solicitud: frollmean (.SD) debería conservar los nombres. De manera más general, froll * debería conservar los nombres si la entrada es similar a una lista con nombres.

Como usuario frecuente de data.table, encuentro extremadamente útil tener funciones de "tiempo consciente", como las que se ofrecen actualmente en el paquete tsibble . Desafortunadamente, este paquete se desarrolla alrededor de dplyr . Me pregunto si una implementación de data.table podría ser posible. Las funciones de ventana propuestas en este número son un subconjunto de esas características.

@ywhcuhk Gracias por sus comentarios, en realidad pensaba que este problema ya pedía demasiado. La mayor parte está bien cubierta por un rollo de paquete aún liviano que es muy rápido. En cuanto a las otras características, sugiero crear un nuevo número para cada característica que le interese, por lo que la discusión sobre si queremos implementar / mantener se puede decidir para cada una por separado. Solo con mirar el archivo Léame de tstibble, no veo nada nuevo que ofrezca ...
Su título es "Tidy Temporal Data Frames" pero ni siquiera parece ofrecer uniones temporales.

Gracias @jangorecki por la respuesta. Tal vez sea un problema que depende del contexto. La estructura de datos con la que trato con más frecuencia se conoce como "datos de panel", con un ID y una hora. Si el programa es "consciente" de esta característica de datos, muchas operaciones, especialmente las operaciones de series de tiempo, serán muy fáciles. Para alguien que conoce STATA, son las operaciones basadas en tsset y xtset , como adelanto, retraso, relleno de brecha, etc. Creo que el "índice" en la tabla de datos se puede mejorar de alguna manera para permitir tales operaciones.

Por supuesto, estas operaciones se pueden realizar en funciones data.table como shift y by . Solo pensé que index en data.table tiene mucho potencial para ser explorado. Estoy de acuerdo en que esto debería pertenecer a un tema diferente. Pero no sé cómo moverlo sin perder las discusiones anteriores ...

¿Fue útil esta página
0 / 5 - 0 calificaciones