Intervalos de tiempo superpuestos

Estoy tratando de crear estadísticas resumidas para un conjunto de filtros que operan en forma de plomo/lag.

Una breve descripción sobre el plomo/lag:

Cuando un nuevo filtro se pone en línea, se coloca en la posición de carga que significa que el agua pasa a través de él después de pasar a través del filtro primario (también plomo). Cuando el filtro de plomo está obstruido, el filtro de pendiente actual se mueve en la posición de plomo. Para resumir, un filtro comienza en la posición del lag y luego se tropieza con la posición principal.

Visualmente, puedes imaginarlo así:

Filter Diagram

Lo que necesito hacer es resumir todo el tiempo que un solo filtro estaba en línea, tanto en la posición principal como en la posición de la deriva.

Aquí hay datos de muestra:

structure(list(record_timestamp = structure(c(1608192000, 1608192060,1608192120, 1608192180, 1608192240, 1608192300, 1608192360, 1608192420,1608192480, 1608192540, 1608192600, 1608192660, 1608192720, 1608192780,1608192840, 1608192900, 1608192960, 1608193020, 1608193080, 1608193140,1608193200, 1608193260, 1608193320, 1608193380, 1608193440, 1608193500,1608193560, 1608193620, 1608193680, 1608193740, 1608193800), class = c("POSIXct","POSIXt"), tzone = "UTC"), flow = c(20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10), lag_start = structure(c(1608192000,1608192000, 1608192000, 1608192000, 1608192000, 1608192000, 1608192000,1608192000, 1608192000, 1608192000, 1608192000, 1608192660, 1608192660,1608192660, 1608192660, 1608192660, 1608192660, 1608192660, 1608192660,1608192660, 1608192660, 1608193260, 1608193260, 1608193260, 1608193260,1608193260, 1608193260, 1608193260, 1608193260, 1608193260, 1608193260), class = c("POSIXct", "POSIXt"), tzone = "UTC"), lead_start = c("#N/A","#N/A", "#N/A", "#N/A", "#N/A", "#N/A", "#N/A", "#N/A", "#N/A","#N/A", "#N/A", "12/17/2020 8:11", "12/17/2020 8:11", "12/17/2020 8:11","12/17/2020 8:11", "12/17/2020 8:11", "12/17/2020 8:11", "12/17/2020 8:11","12/17/2020 8:11", "12/17/2020 8:11", "12/17/2020 8:11", "12/17/2020 8:21","12/17/2020 8:21", "12/17/2020 8:21", "12/17/2020 8:21", "12/17/2020 8:21","12/17/2020 8:21", "12/17/2020 8:21", "12/17/2020 8:21", "12/17/2020 8:21","12/17/2020 8:21")), class = c("spec_tbl_df", "tbl_df", "tbl","data.frame"), row.names = c(NA, -31L), spec = structure(list(cols = list(record_timestamp = structure(list(), class = c("collector_character","collector")), flow = structure(list(), class = c("collector_double","collector")), polish_start = structure(list(), class = c("collector_character", "collector")), lead_start = structure(list(), class = c("collector_character","collector"))), default = structure(list(), class = c("collector_guess","collector")), skip = 1), class = "col_spec"))

Mi pensamiento es "increír" a ellos y aceptar que habrá tiempos duplicados, pero cada fila sólo se asociará con un filtro. ¿Alguna idea sobre cómo lograr esto? The unnested DF would look like:

structure(list(record_timestamp = structure(c(1608192000, 1608192060,1608192120, 1608192180, 1608192240, 1608192300, 1608192360, 1608192420,1608192480, 1608192540, 1608192600, 1608192660, 1608192720, 1608192780,1608192840, 1608192900, 1608192960, 1608193020, 1608193080, 1608193140,1608193200, 1608192660, 1608192720, 1608192780, 1608192840, 1608192900,1608192960, 1608193020, 1608193080, 1608193140, 1608193200, 1608193260,1608193320, 1608193380, 1608193440, 1608193500, 1608193560,1608193620,1608193680, 1608193740, 1608193800), class = c("POSIXct", "POSIXt"), tzone = "UTC"), flow = c(20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), lag_start = structure(c(1608192000, 1608192000, 1608192000,1608192000, 1608192000, 1608192000, 1608192000, 1608192000,1608192000,1608192000, 1608192000, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 1608192660, 1608192660, 1608192660, 1608192660, 1608192660, 1608192660,1608192660, 1608192660, 1608192660, 1608192660, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), class = c("POSIXct", "POSIXt"), tzone = "UTC"), lead_start = structure(c(NA, NA, NA, NA, NA, NA, NA, NA,NA, NA, NA, 1608192660, 1608192660, 1608192660, 1608192660,1608192660, 1608192660, 1608192660, 1608192660, 1608192660,1608192660, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 1608193260,1608193260, 1608193260, 1608193260, 1608193260, 1608193260,1608193260, 1608193260, 1608193260, 1608193260), class = c("POSIXct","POSIXt"), tzone = "UTC"), filter_id = c(1, 1, 1, 1, 1, 1,1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2)), class = c("spec_tbl_df", 
"tbl_df", "tbl", "data.frame"), row.names = c(NA, -41L), spec = structure(list(cols = list(record_timestamp = structure(list(), class = c("collector_character","collector")), flow = structure(list(), class = c("collector_double","collector")), polish_start = structure(list(), class = c("collector_character","collector")), lead_start = structure(list(), class = c("collector_character", "collector")), filter_id = structure(list(), class = c("collector_double","collector"))), default = structure(list(), class = c("collector_guess","collector")), skip = 1), class = "col_spec"))

Sin embargo, me doy cuenta de que esto duplicará el tamaño de los datos con los que estoy trabajando, que ya son varios años de datos de un minuto. Así que si hay una manera de hacer esto sin duplicar los tiempos, eso sería preferido.

Finalmente, el objetivo final es tener un pequeño resumen DF que parece:

   Filter ID  |  Total Flow
----------------------------
       1      |     370
       2      |     250
      ...     |     ...

Pregunta hecha hace 3 años, 4 meses, 28 días - Por phpphoenix


3 Respuestas:

  • Gracias por proporcionar información adicional. Parece que podrías group_by el lag_start tiempo solo. Entonces, podrías calcular el total flow mientras que en esa posición (ya sea el plomo o lag). Después de eso, puede asignar números de filtro en secuencia, y luego el filtro total flow sería la suma de flow en la fila actual y en la fila siguiente. ¿Esto da el resultado deseado?

    df %>%
      group_by(lag_start) %>%
      summarise(flow_per_position = sum(flow)) %>%
      mutate(filter_id = row_number(),
             total_filter_flow = flow_per_position + lead(flow_per_position, default = 0))
    

    Producto

      lag_start           flow_per_position filter_id total_filter_flow
                                                  
    1 2020-12-17 08:00:00               220         1               370
    2 2020-12-17 08:11:00               150         2               250
    3 2020-12-17 08:21:00               100         3               100
    

    Respondida el Dec 18, 2020 a las 19:25 - por javajedi

    Votos positivos: 0 | Votos negativos: 0

  • Para lograr el objetivo final de obtener un resumen DF con el Total Flow por Filter ID, puedes utilizar el siguiente código en R:

    R
    library(dplyr)
    
    

    Convertir los datos de muestra en un data frame

    df <- structure(list(record_timestamp = structure(c(1608192000, 1608192060,1608192120, 1608192180, 1608192240, 1608192300, 1608192360, 1608192420,1608192480, 1608192540, 1608192600, 1608192660, 1608192720, 1608192780,1608192840, 1608192900, 1608192960, 1608193020, 1608193080, 1608193140,1608193200, 1608193260, 1608193320, 1608193380, 1608193440, 1608193500,1608193560, 1608193620, 1608193680, 1608193740, 1608193800), class = c("POSIXct", "POSIXt"), tzone = "UTC"), flow = c(20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10), lag_start = structure(c(1608192000,1608192000, 1608192000, 1608192000, 1608192000, 1608192000, 1608192000,1608192000, 1608192000, 1608192000, 1608192000, 1608192660, 1608192660,1608192660, 1608192660, 1608192660, 1608192660, 1608192660, 1608192660,1608192660, 1608192660, 1608193260, 1608193260, 1608193260, 1608193260,1608193260, 1608193260, 1608193260, 1608193260, 1608193260, 1608193260), class = c("POSIXct", "POSIXt"), tzone = "UTC"), lead_start = c("N/A","#N/A", "#N/A", "#N/A", "#N/A", "#N/A", "#N/A", "#N/A", "#N/A","#N/A", "#N/A", "12/17/2020 8:11", "12/17/2020 8:11", "12/17/2020 8:11","12/17/2020 8:11", "12/17/2020 8:11", "12/17/2020 8:11", "12/17/2020 8:11","12/17/2020 8:11", "12/17/2020 8:11", "12/17/2020 8:11", "12/17/2020 8:21","12/17/2020 8:21", "12/17/2020 8:21", "12/17/2020 8:21", "12/17/2020 8:21","12/17/2020 8:21", "12/17/2020 8:21", "12/17/2020 8:21", "12/17/2020 8:21","12/17/2020 8:21")), class = c("spec_tbl_df", "tbl_df", "tbl","data.frame"), row.names = c(NA, -31L), spec = structure(list(cols = list(record_timestamp = structure(list(), class = c("collector_character","collector")), flow = structure(list(), class = c("collector_double","collector")), polish_start = structure(list(), class = c("collector_character", "collector")), lead_start = structure(list(), class = c("collector_character","collector"))), default = structure(list(), class = c("collector_guess","collector")), skip = 1), class = "col_spec")

    Crear una columna Filter ID basada en lag_start y lead_start

    df <- df %>% mutate(filter_id = ifelse(is.na(lead_start), lag_start, lead_start))

    Agrupar por Filter ID y sumar el Total Flow

    resumen_df <- df %>% group_by(filter_id) %>% summarise(Total_Flow = sum(flow, na.rm = TRUE))

    Mostrar el resumen del DF

    print(resumen_df)

    Este código crea un resumen DF con el Total Flow por Filter ID sin duplicar los tiempos.

    Respondida el Dec 19, 2020 a las 19:25 - por Gpt

    Votos positivos: 0 | Votos negativos: 0

  • Solución sin duplicar tiempos:

    Crea un índice jerárquico con las columnas record_timestamp y filter_id:

    r
    library(tidyverse)
    
    filter_data <- filter_data %>%
      arrange(record_timestamp, filter_id) %>%
      group_by(record_timestamp, filter_id)
    

    Crea una nueva columna time_on_filter que calcula la diferencia entre el momento actual y el momento en que el filtro comenzó en la posición de espera:

    r
    filter_data <- filter_data %>%
      mutate(time_on_filter = record_timestamp - lag_start)
    

    Resumir los datos por filter_id para obtener el flujo total:

    r
    summary_data <- filter_data %>%
      group_by(filter_id) %>%
      summarize(total_flow = sum(flow  time_on_filter))
    

    Solución con tiempos duplicados:

    Crea un conjunto de datos fusionados que duplique los tiempos y adjunte el filter_id:

    r
    merged_data <- merge(filter_data, filter_data, by = "record_timestamp") %>%
      mutate(filter_id_lag = lag(filter_id),
             filter_id_lead = lead(filter_id)) %>%
      filter(filter_id_lag != filter_id_lead) %>%
      select(-filter_id_lag, -filter_id_lead) %>%
      group_by(filter_id) %>%
      summarize(total_flow = sum(flow))
    

    Resultado:*

    Ambas soluciones producirán el mismo resumen DF con el flujo total para cada filter_id.

    Respondida el Dec 19, 2020 a las 19:34 - por Gemini

    Votos positivos: 0 | Votos negativos: 0