varias superponer studio modificar lineas graficos graficas ejes r dataframe grouping counting

superponer - Agrupando y contando para obtener un cierre



superponer graficas en r (5)

Quiero contar por country la cantidad de veces que el status está open y el número de veces que se closed el status . Luego calcule el closerate por country .

Datos:

customer <- c(1,2,3,4,5,6,7,8,9) country <- c(''BE'', ''NL'', ''NL'',''NL'',''BE'',''NL'',''BE'',''BE'',''NL'') closeday <- c(''2017-08-23'', ''2017-08-05'', ''2017-08-22'', ''2017-08-26'', ''2017-08-25'', ''2017-08-13'', ''2017-08-30'', ''2017-08-05'', ''2017-08-23'') closeday <- as.Date(closeday) df <- data.frame(customer,country,closeday)

Agregar status :

df$status <- ifelse(df$closeday < ''2017-08-20'', ''open'', ''closed'') customer country closeday status 1 1 BE 2017-08-23 closed 2 2 NL 2017-08-05 open 3 3 NL 2017-08-22 closed 4 4 NL 2017-08-26 closed 5 5 BE 2017-08-25 closed 6 6 NL 2017-08-13 open 7 7 BE 2017-08-30 closed 8 8 BE 2017-08-05 open 9 9 NL 2017-08-23 closed

Cálculo de closerate

closerate <- length(which(df$status == ''closed'')) / (length(which(df$status == ''closed'')) + length(which(df$status == ''open''))) [1] 0.6666667

Obviamente, este es el closerate del total. El desafío es obtener el closerate por country . Traté de agregar el cálculo closerate a df por:

df$closerate <- length(which(df$status == ''closed'')) / (length(which(df$status == ''closed'')) + length(which(df$status == ''open'')))

Pero le da a todas las líneas un closerate de 0.66 porque no estoy agrupando. Creo que no debería usar la función de longitud porque el conteo se puede hacer agrupando. Leí información sobre el uso de dplyr para contar las salidas lógicas por grupo, pero esto no funcionó.

Este es el resultado deseado:


Aquí hay una solución dplyr .

output <- df %>% count(country, status) %>% group_by(country) %>% mutate(total = sum(n)) %>% mutate(percent = n/total)

Devoluciones...

output country status n total percent BE closed 3 4 0.75 BE open 1 4 0.25 NL closed 3 5 0.60 NL open 2 5 0.40


Aquí hay una solución rápida con tidyverse :

library(dplyr) df %>% group_by(country) %>% mutate(status =ifelse(closeday < ''2017-08-20'', ''open'', ''closed''), closerate=mean(status=="closed"))

De vuelta:

# A tibble: 9 x 5 # Groups: country [2] customer country closeday status closerate <dbl> <fctr> <date> <chr> <dbl> 1 1 BE 2017-08-23 closed 0.75 2 2 NL 2017-08-05 open 0.60 3 3 NL 2017-08-22 closed 0.60 4 4 NL 2017-08-26 closed 0.60 5 5 BE 2017-08-25 closed 0.75 6 6 NL 2017-08-13 open 0.60 7 7 BE 2017-08-30 closed 0.75 8 8 BE 2017-08-05 open 0.75 9 9 NL 2017-08-23 closed 0.60

Aquí estoy utilizando la coerción de lógicos en números enteros cuando el vector de TRUE / FALSE se pone en la función mean() .

Alternativamente, con data.table :

library(data.table) setDT(df)[,status:=ifelse(closeday < ''2017-08-20'', ''open'', ''closed'')] df[, .(closerate=mean(status=="closed")), by=country]


Puedes usar tapply :

data.frame(open=tapply(df$status=="open", df$country, sum), closed=tapply(df$status=="closed", df$country, sum) closerate=tapply(df$status=="closed", df$country, mean))`


Un método data.table sería.

library(data.table) setDT(df)[, {temp <- status=="closed"; # store temporary logical variable .(closed=sum(temp), open=sum(!temp), closeRate=mean(temp))}, # calculate stuff by=country] # by country

que devuelve

country closed open closeRate 1: BE 3 1 0.75 2: NL 3 2 0.60


aggregate(list(output = df$status == "closed"), list(country = df$country), function(x) c(close = sum(x), open = length(x) - sum(x), rate = mean(x))) # country output.close output.open output.rate #1 BE 3.00 1.00 0.75 #2 NL 3.00 2.00 0.60

Hubo una solución que utilizaba la table en los comentarios que parece haber sido eliminada. De todos modos, también podrías usar la table

output = as.data.frame.matrix(table(df$country, df$status)) output$closerate = output$closed/(output$closed + output$open) output # closed open closerate #BE 3 1 0.75 #NL 3 2 0.60