计算R中每个日期的平均个人数

问题描述 投票:0回答:1

我有一个数据集,其中包含不同站点的标记个人(ID)的停留期(start.date到end.date)。我的目标是生成一个列,告诉我每天其他人的平均数量,这些人也出现在同一地点(在每个人的整个居住期间)。

为此,我需要确定每个日期每个站点的个人总数,并计算每个人的总停留时间。最后,我将这个总和除以每个人的总停留天数来计算平均值。任何人都可以帮我完成这个吗?

我用lubridate和dplyr计算了停留天数(total.days)

mutate(total.days = end.date - start.date + 1)

    site    ID  start.date  end.date  total.days
1     1   16      5/24/17     6/5/17    13
2     1   46      4/30/17     5/20/17   21  
3     1   26      4/30/17     5/23/17   24
4     1   89      5/5/17      5/13/17   9
5     1   12      5/11/17     5/14/17   4
6     2   14      5/4/17      5/10/17   7
7     2   18      5/9/17      5/29/17   21
8     2   19      5/24/17     6/10/17   18
9     2   39      5/5/17      5/18/17   14
r dplyr lubridate
1个回答
0
投票

首先,始终建议使用dput(yourData)以更友好的格式提供数据样本,以便其他人可以轻松地重新生成数据。以下是你最好分享的dput()的输出:

> dput(dat)
structure(list(site = c(1, 1, 1, 1, 1, 2, 2, 2, 2), ID = c(16, 
46, 26, 89, 12, 14, 18, 19, 39), start.date = structure(c(17310, 
17286, 17286, 17291, 17297, 17290, 17295, 17310, 17291), class = "Date"), 
end.date = structure(c(17322, 17306, 17309, 17299, 17300, 
17296, 17315, 17327, 17304), class = "Date")), class = "data.frame", row.names = 
c(NA, 
-9L))

要做到这一点,我们首先需要将start.dateend.date解压缩到各个日期:

newDat <- data.frame()
for (i in 1:nrow(dat)){
  expand  <-  data.frame(site = dat$site[i],
                         ID = dat$ID[i],
                         Dates = seq.Date(dat$start.date[i], dat$end.date[i], 1))
  newDat <- rbind(newDat, expand)
}

newDat
    site ID      Dates
1      1 16 2017-05-24
2      1 16 2017-05-25
3      1 16 2017-05-26
4      1 16 2017-05-27
5      1 16 2017-05-28
6      1 16 2017-05-29
7      1 16 2017-05-30
. . . 
. . .

然后我们计算每天每个站点中出现的其他人数:

individualCount = newDat %>%
                     group_by(site, Dates) %>%
                     summarise(individuals = n_distinct(ID) - 1)
individualCount
# A tibble: 75 x 3
# Groups:   site [?]
    site Dates      individuals
   <dbl> <date>           <int>
 1     1 2017-04-30           1
 2     1 2017-05-01           1
 3     1 2017-05-02           1
 4     1 2017-05-03           1
 5     1 2017-05-04           1
 6     1 2017-05-05           2
 7     1 2017-05-06           2
 8     1 2017-05-07           2
 9     1 2017-05-08           2
 10    1 2017-05-09           2
 # ... with 65 more rows

然后,我们使用left_join()使用新信息扩充我们的数据并计算所需的平均值:

newDat <- left_join(newDat, individualCount, by = c("site", "Dates")) %>%
            group_by(site, ID) %>%
            summarise(duration = max(Dates) - min(Dates)+1,
                      av.individuals = mean(individuals))
newDat
# A tibble: 9 x 4
# Groups:   site [?]
   site    ID duration av.individuals
  <dbl> <dbl> <time>            <dbl>
1     1    12 4                  0.75
2     1    16 13                 0   
3     1    26 24                 1.42
4     1    46 21                 1.62
5     1    89 9                  1.33
6     2    14 7                  1.14
7     2    18 21                 0.875
8     2    19 18                 0.333
9     2    39 14                 1.14

最后一步是使用dat再次将所需列添加到原始数据集(left_join()):

dat %>% left_join(newDat, by = c("site", "ID"))
dat
  site ID start.date   end.date   duration av.individuals
1    1 16 2017-05-24 2017-06-05    13 days       0.000000
2    1 46 2017-04-30 2017-05-20    21 days       1.619048
3    1 26 2017-04-30 2017-05-23    24 days       1.416667
4    1 89 2017-05-05 2017-05-13     9 days       2.333333
5    1 12 2017-05-11 2017-05-14     4 days       2.750000
6    2 14 2017-05-04 2017-05-10     7 days       1.142857
7    2 18 2017-05-09 2017-05-29    21 days       0.857143
8    2 19 2017-05-24 2017-06-10    18 days       0.333333
9    2 39 2017-05-05 2017-05-18    14 days       1.142857
© www.soinside.com 2019 - 2024. All rights reserved.