基于时间段创建群组

3

我可以帮你创建一个基于5年步长的新分组变量,与你的数据相关的IT技术内容。请看下面的示例:

假设你有以下数据:

group <- c(rep("A", 7), rep("B", 10))
year <- c(2008:2014, 2005:2014)
dat <- data.frame(group, year)

   group year
1      A 2008
2      A 2009
3      A 2010
4      A 2011
5      A 2012
6      A 2013
7      A 2014
8      B 2005
9      B 2006
10     B 2007
11     B 2008
12     B 2009
13     B 2010
14     B 2011
15     B 2012
16     B 2013
17     B 2014

到这里:
 > dat
   group year    period
1      A 2008 2005_2009
2      A 2009 2005_2009
3      A 2010 2010_2014
4      A 2011 2010_2014
5      A 2012 2010_2014
6      A 2013 2010_2014
7      A 2014 2010_2014
8      B 2005 2005_2009
9      B 2006 2005_2009
10     B 2007 2005_2009
11     B 2008 2005_2009
12     B 2009 2005_2009
13     B 2010 2010_2014
14     B 2011 2010_2014
15     B 2012 2010_2014
16     B 2013 2010_2014
17     B 2014 2010_2014

我想我可以使用cut(dat$year, breaks = ??),但我不知道如何设置断点。

2个回答

4
这是一种实现方式:
dat$period <- paste(min <- floor(dat$year/5)*5, min+4,sep = "_")

我猜这里的诀窍是使用 floor(year/x)*x 函数获得小于你的年份的最大整数。
这里提供了一个通用的版本:
x <- 5
yearstart <- 2000
dat$period <- paste(min <- floor((dat$year-yearstart)/x)*x+yearstart,
                    min+x-1,sep = "_")

您可以使用yearstart来确保例如年份2000是一组中的第一个,当x不是它的倍数时。

非常出色。我认为在效率方面很难超越那个。 - David Arenburg
谢谢,对我的示例很有效。但是是否可以调整为例如10年的间隔(如果我尝试,会创建一个2010_1019的间隔)? - erc
10年的工作对我也是一样的:paste(min <- floor(dat$year/10)*10, min+9,sep = "_")。很好的解决方案! - fdetsch
1
@beetroot 我已经添加了一个通用的例子! - Therkel
1
你可以避免使用 floor,而是使用整数除法 %/%。例如 (dat$year%/%5)*5 - nicola

1
如果您从“year”列创建实际的Date对象,那么cut应该完成任务。
## convert 'year' column to dates
yrs <- paste0(dat$year, "-01-01")
yrs <- as.Date(yrs)

## create cuts of 5 years and add them to data.frame
dat$period <- cut(yrs, "5 years")

## create desired factor levels
library(lubridate)

lvl <- as.Date(levels(dat$period))
lvl <- paste(year(lvl), year(lvl) + 4, sep = "_")
levels(dat$period) <- lvl

head(dat)
  group year    period
1     A 2008 2005_2009
2     A 2009 2005_2009
3     A 2010 2010_2014
4     A 2011 2010_2014
5     A 2012 2010_2014
6     A 2013 2010_2014

谢谢,有没有一种方法可以自动创建时间段的级别?我的实际数据集跨越了200多年,这将是很繁琐的... - erc
1
当然,@beetroot。看一下上面的更新。只需使用lubridate中的year来创建每个时期的起始点和结束点。 - fdetsch

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接