我有一个包含两列Id和Date的数据集,如下所示,使用玩具数据集。
Id Date
5373283 2010-11-05
5373283 2014-11-05
5373283 2001-07-13
5373283 2007-12-01
5373283 2015-07-07
3475684 2015-05-19
3475684 2010-06-24
我想检查each id
的任何日期是否在2年范围内。如果是,则列将显示是,否则,否。最终输出将如此
Id Status
5373283 Yes
3475684 No
Yes
的{p> Id 5373283
因为2014-11-05
和2015-07-07
这两个日期相隔两年。 No
Id 3475684
,因为这两个日期相差超过2年。任何帮助完成这一点非常感谢。
答案 0 :(得分:2)
假设数据。
DF <- data.frame(id = c(1, 1, 1, 2, 2),
date = c("2010-10-9", "2012-10-8", "2008-10-5",
"2007-7-5", "2009-7-5"), stringsAsFactors = FALSE)
以下代码按ID显示最小间隔(以天为单位)。
发生的事情是:
mutate
将日期重新定义为Date
类
arrange
按日期对数据进行排序
group_by
告诉每个ID应该进行以下计算,
summarize
计算最小差异。
library(dplyr)
DF %>% mutate(date = as.Date(date)) %>%
arrange(date) %>%
group_by(id) %>%
summarize(diffmin = as.numeric(min(diff(date)), units = "days"))
# id diffmin
# (dbl) (dbl)
#1 1 730
#2 2 731
如果您可以忽略闰年,则小于或等于730意味着在2年内。请注意,2007-7-5
和2009-7-5
之间的差异为731天,因此判断为2年。
如果这对你不好,简单的日差是不够的。我需要定义一个自定义检查器功能。
check2years <- function(a, b) {
# check if b - a <= 2 years
# assumes a and b are Date
yr_a <- format(a, "%Y") %>% as.integer()
yr_b <- format(b, "%Y") %>% as.integer()
dy_a <- format(a, "%m-%d")
dy_b <- format(b, "%m-%d")
(yr_b - yr_a < 2) | ((yr_b - yr_a == 2) & (dy_b >= dy_a))
}
然后,您可以通过以下方式检查任何组合是否在2年内。
DF %>% mutate(date = as.Date(date)) %>%
arrange(date) %>%
group_by(id) %>%
summarize(within2yr = any(check2years(head(date, length(date)-1),
tail(date, length(date)-1))))
# id within2yr
# (dbl) (lgl)
#1 1 TRUE
#2 2 TRUE
答案 1 :(得分:2)
您也可以在没有任何库的情况下解决此问题:
使用您的示例:
Id = c(5373283,5373283,5373283,5373283,5373283,3475684,3475684)
Date = as.Date(c("2010-11-05","2014-11-05","2001-07-13","2007-12-01","2015-07-07","2015-05-19","2010-06-24"))
df = data.frame(Id,Date)
> df
Id Date
7 3475684 2010-06-24
6 3475684 2015-05-19
3 5373283 2001-07-13
4 5373283 2007-12-01
1 5373283 2010-11-05
2 5373283 2014-11-05
5 5373283 2015-07-07
执行以下操作:
订购数据
df = df[order(df$Id,df$Date),]
aggregate
按ID执行min(diff(x))
,其中x是每个Id的日期。
z = aggregate(df$Date,by = list(Id = df$Id),FUN = function(x){min(diff(x))})
此功能的作用是返回相邻日期之间的最低差异。这就是您需要先订购数据框的原因 这将返回:
> z
Id x
1 3475684 1790
2 5373283 244
列x
是天数的最小差异。
x
是否小于或等于2 * 365
z$result = z$x<=2*365
,并提供:
Id x result
1 3475684 1790 FALSE
2 5373283 244 TRUE
最终代码
df = df[order(df$Id,df$Date),]
z = aggregate(df$Date,by = list(Id = df$Id),FUN = function(x){min(diff(x))})
z$result = z$x>=2*365
答案 2 :(得分:1)
您可以在库dplyr
中使用类似的内容,以便为每个ID按排序顺序排列前两个日期,并查看它们是否相差两年:
library(dplyr)
df$Date <- as.Date(df$Date)
df %>%
group_by(Id) %>%
summarise(Status = as.numeric(difftime(max(Date), Date[order(Date, decreasing = TRUE)][2], units = 'days')) < 730)
输出如下:
Source: local data frame [2 x 2]
Id Status
(int) (lgl)
1 3475684 FALSE
2 5373283 TRUE