Expandir rangos definidos por las columnas "desde" y "hasta"
Este problema también se conoce como "transformar un conjunto de datos de "inicio-fin" en un conjunto de datos de panel".
Tengo un marco de datos que contiene "name"
los presidentes de EE. UU., los años en que comienzan y terminan en el cargo ( "from"
y "to"
columnas). Aquí hay una muestra:
presidents <- data.frame(
name = c("Bill Clinton", "George W. Bush", "Barack Obama"),
from = c(1993, 2001, 2009),
to = c(2001, 2009, 2012)
)
presidents
#> name from to
#> 1 Bill Clinton 1993 2001
#> 2 George W. Bush 2001 2009
#> 3 Barack Obama 2009 2012
Quiero crear un marco de datos con dos columnas ( "name"
y "year"
), con una fila por cada año que un presidente estuvo en el cargo. Por lo tanto, necesito crear una secuencia regular cada año desde " from
" hasta "to"
. Aquí está mi salida esperada:
name year
Bill Clinton 1993
Bill Clinton 1994
...
Bill Clinton 2000
Bill Clinton 2001
George W. Bush 2001
George W. Bush 2002
...
George W. Bush 2008
George W. Bush 2009
Barack Obama 2009
Barack Obama 2010
Barack Obama 2011
Barack Obama 2012
Sé que puedo utilizarlo data.frame(name = "Bill Clinton", year = seq(1993, 2001))
para ampliar las cosas para un solo presidente, pero no sé cómo repetirlo para cada presidente.
¿Cómo hago esto? Siento que debería saber esto, pero me estoy quedando en blanco.
Actualización 1
Bien, probé ambas soluciones y aparece un error:
foo<-structure(list(name = c("Grover Cleveland", "Benjamin Harrison", "Grover Cleveland"), from = c(1885, 1889, 1893), to = c(1889, 1893, 1897)), .Names = c("name", "from", "to"), row.names = 22:24, class = "data.frame")
ddply(foo, "name", summarise, year = seq(from, to))
Error in seq.default(from, to) : 'from' must be of length 1
Aquí tienes una data.table
solución. Tiene la característica interesante (aunque menor) de dejar a los presidentes en el orden en el que se encuentran:
library(data.table)
dt <- data.table(presidents)
dt[, list(year = seq(from, to)), by = name]
# name year
# 1: Bill Clinton 1993
# 2: Bill Clinton 1994
# ...
# ...
# 21: Barack Obama 2011
# 22: Barack Obama 2012
Editar: para manejar presidentes con mandatos no consecutivos, use esto en su lugar:
dt[, list(year = seq(from, to)), by = c("name", "from")]
Puedes utilizar el plyr
paquete:
library(plyr)
ddply(presidents, "name", summarise, year = seq(from, to))
# name year
# 1 Barack Obama 2009
# 2 Barack Obama 2010
# 3 Barack Obama 2011
# 4 Barack Obama 2012
# 5 Bill Clinton 1993
# 6 Bill Clinton 1994
# [...]
y si es importante que los datos estén ordenados por año, puedes utilizar la arrange
función:
df <- ddply(presidents, "name", summarise, year = seq(from, to))
arrange(df, df$year)
# name year
# 1 Bill Clinton 1993
# 2 Bill Clinton 1994
# 3 Bill Clinton 1995
# [...]
# 21 Barack Obama 2011
# 22 Barack Obama 2012
Edición 1: A continuación de la "Actualización 1" de @edgester, un enfoque más apropiado es utilizar adply
para contabilizar a los presidentes con mandatos no consecutivos:
adply(foo, 1, summarise, year = seq(from, to))[c("name", "year")]