R: Variables de sumo basadas en alguna condición

Dada una tabla, estoy tratando de aprender a usar R para resumir variables basadas en cuando se cumple una determinada condición (basado en otras variables en la misma tabla).

Usando la biblioteca dplyr (creé algunos datos) y luego resumí los datos por grupos:

#load library
library(dplyr)

#create data
data <- data.frame(
    
    "col_a" = c("aaa", "aaa", "aaa", "aaa", "aaa", "aaa", "aaa", "aaa"),
    "col_b" = c("123", "124", "125", "126", "127", "128", "129", "130"),
"col_c" = c("2015", "2015", "2015", "2015", "2015", "2015", "2015", "2015"),
"col_d" = c("red", "red", "red", "blue", "blue", "green", "green", "green"),
"day_a" = c("2001-01-01", "2000-01-05", "2000-01-01", "2010-12-20", "2010-12-20", "2020-05-05", "2020-05-05", "2020-05-28"),
"day_b" = c("2001-01-10", "2000-01-10", "2000-01-01", "2010-12-25", "2010-12-22", "2020-05-15", "2020-05-20", "2020-05-30")

)

#format variable types

data$col_a = as.factor(data$col_a)
data$col_b = as.factor(data$col_b)
data$col_c = as.factor(data$col_c)

#format date variables
data$day_a = as.factor(data$day_a)
data$day_b = as.factor(data$day_b)

data$day_1 = as.Date(as.character(data$day_a))
data$day_2 = as.Date(as.character(data$day_b))

#create new variable based on difference between date variables
data$diff = data$day_2 - data$day_1
data$diff = as.numeric(data$diff)

#create file that sums days based on groups of "col_a, col_c, col_d"
file = data%>%
    group_by(col_a, col_c, col_d) %>% 
    dplyr::summarize(Total = sum(diff, na.rm=TRUE), Count = n()) 

file = as.data.frame(file)

Ahora, para grupos de "col_a, col_c, col_d", quiero resumir la variable "diff" basada en otra condición.

Por ejemplo, para el grupo "aaaa, 2015, verde", sólo quiero resumir los "días únicas" - es decir, los días que superponen. (2020-05-05, 2020-05-15), ( 2020-05-05, 2020-05-20), (2020-05-28 ,2020-05-30)

Para este grupo, quiero el valor de la variable "total" = 15 + 2 = 17 ... en lugar de "27".

Esto se debe a que las fechas (2020-05-05, 2020-05-15) están completamente dentro de las fechas ( 2020-05-05, 2020-05-20). Sólo quiero resumir los períodos de cita "unique".

Estoy tratando de conseguir algo al final que parece esto:

final_result <- data.frame ( col_a = c("aaa", "aaa", "aaa"),
                             col_c = c("2015", "2015", "2015"), 
                             col_d = c("blue", "green", "red"),
                             total = c("5","17","9"),
count = c("2", "3", "3")
                                 
    )

¿Puede alguien enseñarme cómo hacer esto?

Gracias.

Pregunta hecha hace 3 años, 5 meses, 0 días - Por debugdragon


3 Respuestas:

  • Aquí hay un acercamiento con purrr::map2:

    Primero, convertir el Date columnas a representaciones enteros. Entonces usa map2 crear vectores de las secuencias enteros entre las dos fechas. Parece que no quieres contar el último día, así que he subido 1 de day 2.

    Ahora tenemos una nueva columna dates que tiene un vector de fechas como enteros.

    library(purrr)
    data %>% 
      transmute(dates = map2(as.integer(day_1),as.integer(day_2)-1,seq))
    1                                           11323, 11324, 11325, 11326, 11327, 11328, 11329, 11330, 11331
    2                                                                       10961, 10962, 10963, 10964, 10965
    3                                                                                            10957, 10956
    4                                                                       14963, 14964, 14965, 14966, 14967
    5                                                                                            14963, 14964
    6                                    18387, 18388, 18389, 18390, 18391, 18392, 18393, 18394, 18395, 18396
    7 18387, 18388, 18389, 18390, 18391, 18392, 18393, 18394, 18395, 18396, 18397, 18398, 18399, 18400, 18401
    8                                                                                            18410, 18411
    

    Entonces podemos agrupar como lo hiciste anteriormente, y resumir al unlistar las fechas para un grupo específico y usar unique para eliminar duplicados. Entonces cuenta el número de fechas.

    data %>% 
      mutate(dates = map2(as.integer(day_1),as.integer(day_2)-1,seq)) %>%
      group_by(col_a, col_c, col_d) %>%
      dplyr::summarize(Total = length(unique(unlist(dates))), Count = n())
    # A tibble: 3 x 5
    # Groups:   col_a, col_c [1]
      col_a col_c col_d Total Count
          
    1 aaa   2015  blue      5     2
    2 aaa   2015  green    17     3
    3 aaa   2015  red      16     3
    

    Respondida el Dec 17, 2020 a las 02:25 - por codercentaur

    Votos positivos: 0 | Votos negativos: 0

  • Para lograr el resultado deseado en R, puedes usar el siguiente código. Primero, necesitas identificar las fechas únicas dentro de cada grupo y luego sumar la diferencia de días solo para esas fechas únicas.

    Aquí está el código que puedes utilizar:

    R
    

    Calcular las fechas únicas dentro de cada grupo

    data_unique <- data %>% group_by(col_a, col_c, col_d) %>% summarize(unique_dates = list(unique(c(day_1, day_2)))

    Definir una función para sumar la diferencia de días solo para las fechas únicas

    sum_unique_diff <- function(unique_dates) { unique_dates <- unique_dates[[1]] total_diff <- 0 if (length(unique_dates) > 1) { unique_dates <- unique_dates[order(unique_dates)] for (i in 1:(length(unique_dates)-1)) { if (unique_dates[i+1] > unique_dates[i]) { total_diff <- total_diff + as.numeric(unique_dates[i+1] - unique_dates[i]) } } } return(total_diff) }

    Aplicar la función a cada grupo y calcular el total y contar

    final_result <- data_unique %>% mutate(total = sapply(unique_dates, sum_unique_diff), count = sapply(unique_dates, length)) %>% select(col_a, col_c, col_d, total, count) print(final_result)

    Este código primero encuentra las fechas únicas dentro de cada grupo. Luego, define una función sum_unique_diff que calcula la suma de las diferencias de días solo para las fechas únicas. Finalmente, aplica esta función a cada grupo y obtiene el total y el recuento necesarios.

    Al ejecutar este código, obtendrás un dataframe final_result que contiene los valores sumarizados según las fechas únicas dentro de cada grupo. Espero que esta solución sea útil para ti. ¡Si tienes alguna otra pregunta, no dudes en preguntar!

    Respondida el Dec 18, 2020 a las 02:23 - por Gpt

    Votos positivos: 0 | Votos negativos: 0

  • Para resumir la variable "diff" basada en la condición de días únicos que se superponen, puedes utilizar la función distinct en R. Esta función elimina las filas duplicadas de un marco de datos, basándose en las columnas especificadas.

    Aquí tienes un código modificado que implementa esta solución:

    r
    

    Cargar la biblioteca dplyr

    library(dplyr)

    Crear datos

    data <- data.frame( "col_a" = c("aaa", "aaa", "aaa", "aaa", "aaa", "aaa", "aaa", "aaa"), "col_b" = c("123", "124", "125", "126", "127", "128", "129", "130"), "col_c" = c("2015", "2015", "2015", "2015", "2015", "2015", "2015", "2015"), "col_d" = c("red", "red", "red", "blue", "blue", "green", "green", "green"), "day_a" = c("2001-01-01", "2000-01-05", "2000-01-01", "2010-12-20", "2010-12-20", "2020-05-05", "2020-05-05", "2020-05-28"), "day_b" = c("2001-01-10", "2000-01-10", "2000-01-01", "2010-12-25", "2010-12-22", "2020-05-15", "2020-05-20", "2020-05-30") )

    Formatear tipos de variables

    data$col_a = as.factor(data$col_a) data$col_b = as.factor(data$col_b) data$col_c = as.factor(data$col_c)

    Formatear variables de fecha

    data$day_a = as.factor(data$day_a) data$day_b = as.factor(data$day_b) data$day_1 = as.Date(as.character(data$day_a)) data$day_2 = as.Date(as.character(data$day_b))

    Crear nueva variable basada en la diferencia entre variables de fecha

    data$diff = data$day_2 - data$day_1 data$diff = as.numeric(data$diff)

    Eliminar filas duplicadas basadas en "day_a" y "day_b"

    data_distinct <- data %>% group_by(day_a, day_b) %>% distinct()

    Resumir la variable "diff" basada en grupos de "col_a", "col_c" y "col_d"

    file <- data_distinct %>% group_by(col_a, col_c, col_d) %>% summarize(Total = sum(diff, na.rm = TRUE), Count = n()) file <- as.data.frame(file)

    El resultado, file, es un marco de datos que contiene la suma y el recuento de las diferencias únicas superpuestas, agrupadas por col_a, col_c y col_d.

    Ten en cuenta que este código solo funciona si las fechas de inicio y finalización de cada intervalo de fechas se almacenan en columnas separadas. Si todos los intervalos de fechas se almacenan en una sola columna, tendrás que modificar el código para adaptarlo a tu estructura de datos específica.

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

    Votos positivos: 0 | Votos negativos: 0