按R中的组计算日期之间的差异

时间:2016-11-13 03:19:31

标签: r date-arithmetic

我使用物流曝光来计算鸟巢的孵化成功率。我的数据集非常广泛,我有大约2,000个巢,每个巢都有一个唯一的ID(" ClutchID)。我需要计算给定巢暴露的天数("曝光"),或者更简单地说,是第1天和最后一天之间的差异。我使用了以下代码:

HS_Hatch$Exposure=NA    
for(i in 2:nrow(HS_Hatch)){HS_Hatch$Exposure[i]=HS_Hatch$DateVisit[i]- HS_Hatch$DateVisit[i-1]}

其中HS_Hatch是我的数据集,DateVisit是实际日期。唯一的问题是R正在计算第一个日期的曝光值(这没有意义)。

我真正需要的是计算给定离合器的第一个和最后一个日期之间的差异。我还调查了以下内容:

Exposure=ddply(HS_Hatch, "ClutchID", summarize, 
                     orderfrequency = as.numeric(diff.Date(DateVisit)))


df %>%
  mutate(Exposure =  as.Date(HS_Hatch$DateVisit, "%Y-%m-%d")) %>%
  group_by(ClutchID) %>%
  arrange(Exposure) %>%
  mutate(lag=lag(DateVisit), difference=DateVisit-lag)

我还在学习R所以任何帮助都会受到高度赞赏。

编辑: 以下是我使用

的数据示例
HS_Hatch <- structure(list(ClutchID = c(1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 
                                        2L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 4L, 4L, 5L, 5L, 5L, 5L, 5L, 5L
), DateVisit = c("3/15/2012", "3/18/2012", "3/20/2012", "4/1/2012", 
                 "4/3/2012", "3/18/2012", "3/20/2012", "3/22/2012", "4/3/2012", 
                 "4/4/2012", "3/22/2012", "4/3/2012", "4/4/2012", "3/18/2012", 
                 "3/20/2012", "3/22/2012", "4/2/2012", "4/3/2012", "4/4/2012", 
                 "3/20/2012", "3/22/2012", "3/25/2012", "3/27/2012", "4/4/2012", 
                 "4/5/2012"), Year = c(2012L, 2012L, 2012L, 2012L, 2012L, 2012L, 
                                       2012L, 2012L, 2012L, 2012L, 2012L, 2012L, 2012L, 2012L, 2012L, 
                                       2012L, 2012L, 2012L, 2012L, 2012L, 2012L, 2012L, 2012L, 2012L, 
                                       2012L), Survive = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
                                                           1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L)), class = c("tbl_df", 
                                                                                                                               "tbl", "data.frame"), row.names = c(NA, -25L), .Names = c("ClutchID", 
                                                                                                                                                                                         "DateVisit", "Year", "Survive"), spec = structure(list(cols = structure(list(
                                                                                                                                                                                             ClutchID = structure(list(), class = c("collector_integer", 
                                                                                                                                                                                                                                    "collector")), DateVisit = structure(list(), class = c("collector_character", 
                                                                                                                                                                                                                                                                                           "collector")), Year = structure(list(), class = c("collector_integer", 
                                                                                                                                                                                                                                                                                                                                             "collector")), Survive = structure(list(), class = c("collector_integer", 
                                                                                                                                                                                                                                                                                                                                                                                                  "collector"))), .Names = c("ClutchID", "DateVisit", "Year", 
                                                                                                                                                                                                                                                                                                                                                                                                                             "Survive")), default = structure(list(), class = c("collector_guess", 
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                "collector"))), .Names = c("cols", "default"), class = "col_spec"))

2 个答案:

答案 0 :(得分:3)

收集一些评论......

加载dplyr

对于此问题,我们只需要dplyr包。如果我们加载其他包,例如plyr,如果两个包具有相同名称的函数,则可能会导致冲突。我们只加载dplyr

library(dplyr)

将来,您可能希望加载tidyverse - 它包括dplyr和其他相关包,用于图形等。

转换日期

让我们将DateVisit变量从字符串转换为R可以解释为日期的东西。一旦我们这样做,它允许R通过相互减去两个日期来计算天数差异。

HS_Hatch <- HS_Hatch %>%
 mutate(date_visit = as.Date(DateVisit, "%m/%d/%Y"))

日期格式%m/%d/%Y与原始代码不同。此日期格式需要与日期在数据中的显示方式相匹配。 DateVisit的日期为月/日/年,因此我们使用%m/%d/%Y

此外,您无需在DateVisit中指定mutate内的HS_Hatch$DateVisit数据集,因为它已在HS_Hatch中查找。代码HS_Hatch %>% ...表示“使用HS_Hatch执行以下步骤”。

计算曝光量

要计算曝光率,我们需要找到ClutchID的每组行的第一个日期,最后日期,然后是两者之间的差异。我们使用summarize,每个ClutchID将数据折叠为一行。

exposure <- HS_Hatch %>% 
    group_by(ClutchID) %>%
    summarize(first_visit = min(date_visit), 
              last_visit = max(date_visit), 
              exposure = last_visit - first_visit)

first_visit = min(date_visit)会分别找到每个date_visit的最低ClutchID,因为我们使用的是group_by(ClutchID)

exposure = last_visit - first_visit获取新计算的first_visitlast_visit,并找出天数的差异。

这会产生以下结果:

  ClutchID first_visit last_visit exposure
     <int>      <date>     <date>    <dbl>
1        1  2012-03-15 2012-04-03       19
2        2  2012-03-18 2012-04-04       17
3        3  2012-03-22 2012-04-04       13
4        4  2012-03-18 2012-04-04       17
5        5  2012-03-20 2012-04-05       16

如果您想保留所有原始行,可以使用mutate代替summarize

答案 1 :(得分:0)

如果您从向量date中查找以日为单位的difftime结果,并且在新列中不产生NA值,并且希望按多个条件/组进行分组,则这是类似的解决方案。

请确保您的日期向量已按照前面说明的正确格式进行了转换。

dat2 <- dat %>% 
select(group1, group2, date) %>% 
arrange(group1, group2, date) %>% 
group_by(group1, group2) %>% 
mutate(diff_date = c(0,diff(date)))