Contando observaciones en cada año desde un rango de fecha en dplyr
Digamos que tengo un data.frame consistente en tipo de industria y fechas de inicio y finalización (por ejemplo, para un empleado).
mydf <- data.frame(industry = c("Government", "Education", "Military", "Private Sector", "Government", "Private Sector"),
start_date = c("2014-01-01", "2016-02-01", "2012-11-01", "2013-03-01", "2012-12-01", "2011-12-01"),
end_date = c("2020-12-01", "2016-10-01", "2014-01-01", "2016-10-01", "2015-10-01", "2014-09-01"))
> mydf
industry start_date end_date
1 Government 2014-01-01 2020-12-01
2 Education 2016-02-01 2016-10-01
3 Military 2012-11-01 2014-01-01
4 Private Sector 2013-03-01 2016-10-01
5 Government 2012-12-01 2015-10-01
6 Private Sector 2011-12-01 2014-09-01
Me gustaría crear un gráfico de barras apilada en el que cada año único en el start_date
columna está en el eje X (por ejemplo, 2011-2016) y el eje y representa el número total de observaciones (el recuento de filas) representadas en una determinada industria para ese año.
No estoy seguro de cuál es la manera correcta de manipular los datos. marco para permitir esto. Probablemente necesitaría manipular los datos para tener columnas para industry
year
y count
. Pero no estoy seguro de cómo producir las columnas del año de un rango de fechas. ¿Alguna idea?
Pregunta hecha hace 3 años, 5 meses, 0 días - Por pixelprodigy
4 Respuestas:
-
Convertir las columnas de fecha en
Date
, crear la fecha 'seq
uence from the 'start_date' to 'end_date' for each row withmap2
(depurrr
),unnest
ellist
producción,count
elyear
y trama congeom_bar
library(dplyr) library(tidyr) library(purrr) library(ggplot2) mydf %>% mutate(across(c(start_date, end_date), as.Date)) %>% transmute(industry, date = map2(start_date, end_date, seq, by = 'day')) %>% unnest(c(date)) %>% count(industry, year = factor(year(date))) %>% ggplot(aes(x = year, y = n, fill = industry)) + geom_col() + theme_bw()
Si la trama debe ser separada para cada 'industria'
mydf %>% mutate(across(c(start_date, end_date), as.Date)) %>% transmute(industry, date = map2(start_date, end_date, seq, by = 'day')) %>% unnest(c(date)) %>% count(industry, year = factor(year(date))) %>% ggplot(aes(x = year, y = n, fill = industry)) + geom_col() + facet_wrap(~ industry) + theme_bw()
- ¡Fuera!
Como sugirió @IanCampbell, el
by
paraseq
puede ser'year'
mydf %>% mutate(across(c(start_date, end_date), as.Date)) %>% transmute(industry, date = map2(start_date, end_date, seq, by = 'year')) %>% unnest(c(date)) %>% count(industry, year = factor(year(date))) %>% ggplot(aes(x = year, y = n, fill = industry)) + geom_col() + facet_wrap(~ industry) + theme_bw()
Respondida el Dec 16, 2020 a las 20:09 - por javajedi
Votos positivos: 0 | Votos negativos: 0 -
¿Es esto lo que estás buscando? Yo recomendaría usar
purrr::pmap
crear un nuevo marco de datos con una fila para cada año basado en cada fila de los datos originales.Podemos usar el
purrr::pmap_dfr
para devolver automáticamente un único marco de datos ligado por fila.Podemos usar el
~with(list(...), )
truco para poder referenciar columnas por nombre.Entonces podemos usar
dplyr::count
contar por combinaciones de columnas. Entonces es fácil.library(dplyr) library(purrr) library(lubridate) library(ggplot) mydf %>% mutate(across(c(start_date, end_date), as.Date), start_year = year(start_date), end_year = year(end_date)) %>% pmap_dfr(~with(list(...),data.frame(industry, year = seq(start_year, end_year)))) %>% count(year, industry) %>% ggplot(aes(x = year, y = n, fill = industry)) + geom_bar(stat="identity")
Respondida el Dec 16, 2020 a las 20:16 - por scriptsphinx
Votos positivos: 0 | Votos negativos: 0 -
Para lograr esto en dplyr, primero necesitas generar una secuencia de años entre la fecha de inicio y la fecha de finalización de cada observación. Luego agrupar por año e industria y contar el número de observaciones en cada grupo.
Aquí tienes un ejemplo de cómo hacerlo:
R library(dplyr) library(tidyr)
Convertir las fechas a tipo Date
mydf$start_date <- as.Date(mydf$start_date) mydf$end_date <- as.Date(mydf$end_date)Generar secuencia de años para cada observación
mydf <- mydf %>% mutate(year = map2(start_date, end_date, ~ seq(., .x, by = "year"))) %>% unnest(year)Contar observaciones por industria y año
result <- mydf %>% count(industry, year) %>% arrange(year)Crear el gráfico de barras apilado
library(ggplot2) ggplot(result, aes(x = as.character(year), y = n, fill = industry)) + geom_bar(stat = "identity")En este código:
- Primero convertimos las columnas de fecha a tipo `Date` para facilitar la manipulación de fechas.
- Luego generamos una secuencia de años entre la fecha de inicio y finalización de cada observación usando la función `map2` de `purrr`.
- Desagregamos la columna de años generada para que cada fila represente un año único.
- Contamos el número de observaciones por industria y año.
- Creamos un gráfico de barras apilado donde el eje X representa los años, el eje Y el recuento de observaciones y las barras están apiladas por industria.
Con estos pasos, podrás visualizar el número total de observaciones por industria para cada año en un gráfico de barras apilado.
Respondida el Dec 17, 2020 a las 20:05 - por Gpt
Votos positivos: 0 | Votos negativos: 0 -
Usando la función
cut
dedplyr
:library(dplyr) mydf %>% mutate(year = cut(start_date, breaks = "year")) %>% group_by(year, industry) %>% tally() %>% ggplot(aes(x = year, y = n, fill = industry)) + geom_bar(stat = "identity")
Explicación:
cut(start_date, breaks = "year")
crea una nueva columnayear
que asigna cada fila a un año determinado en función de la fecha de inicio.group_by(year, industry)
agrupa las filas por año e industria.tally()
cuenta el número de observaciones en cada grupo.ggplot()
crea un gráfico de barras apiladas con el año en el eje x, el recuento en el eje y y la industria como relleno.Usando la función
lubridate
:library(lubridate) mydf %>% mutate(year = year(start_date)) %>% group_by(year, industry) %>% tally() %>% ggplot(aes(x = year, y = n, fill = industry)) + geom_bar(stat = "identity")
Explicación:
year(start_date)
delubridate
extrae el año de la columnastart_date
. El resto del código es similar al ejemplo anterior.Usando la función
tidyr
:library(tidyr) mydf %>% mutate(year = as.numeric(as.character(start_date))) %>% pivot_longer(cols = 1:6, names_to = "variable", values_to = "value") %>% filter(variable == "start_date") %>% mutate(year = year(value)) %>% group_by(year, industry) %>% tally() %>% ggplot(aes(x = year, y = n, fill = industry)) + geom_bar(stat = "identity")
Explicación:
pivot_longer()
convierte el marco de datos en formato largo, con una columna para cada variable original.filter(variable == "start_date")
selecciona solo las filas que contienen las fechas de inicio. * El resto del código es similar a los ejemplos anteriores.Respondida el Dec 17, 2020 a las 20:16 - por Gemini
Votos positivos: 0 | Votos negativos: 0