如何根据日期计算汇总数据

时间:2017-05-28 02:07:53

标签: r date dataframe

我的数据看起来像这样(注意日期是DD-MM-YYYY格式):

ID  date      drug  score
A   28/08/2016  2   3
A   29/08/2016  1   4
A   30/08/2016  2   4
A   2/09/2016   2   4
A   3/09/2016   1   4
A   4/09/2016   2   4
B   8/08/2016   1   3
B   9/08/2016   2   4
B   10/08/2016  2   3
B   11/08/2016  1   3
C   30/11/2016  2   4
C   2/12/2016   1   5
C   3/12/2016   2   1
C   5/12/2016   1   4
C   6/12/2016   2   4
C   8/12/2016   1   2
C   9/12/2016   1   2    

对于药物':1 =服用药物,2 =没服用药物。

我需要总结每个ID:

  • 0day:服用药物的天数的平均分数。
  • -1day:药物服用前几天的平均得分。
  • + 1day:药物服用后不久的平均得分。

如果药物连续服用2天(例如该例子的最后2行),那么这些分数不应计入-1天或+ 1天的计算中(即最后两行中的每一行都有助于0day分数,但不会对其他指标做出贡献。)

因此对于这个示例数据,我需要一个像这样的输出表:

    -1day   0day      +1day
A   3.5     4         4
B   3       3         4
C           3.25      2.5

请注意,所有日期都没有记录,并且-1day和+ 1day计算需要基于实际日期,而不仅仅是数据集中的记录。

我不知道该怎么做。

我还有两个额外的奖励问题:

  • 我很可能还需要计算-2day和+ 2day的分数,所以需要能够调整答案来做到这一点。

  • 我怎样才能计算出NoDrug评分,即无法在服药一天的5天内所有日子的平均值。

以下是使用此示例数据生成数据框的代码:

data<-data.frame(ID=c("A","A","A","A","A","A","B","B","B","B","C","C","C","C","C","C","C"),
                 date=as.Date(c("28/08/2016","29/08/2016","30/08/2016","2/09/2016","3/09/2016","4/09/2016","8/08/2016","9/08/2016","10/08/2016","11/08/2016","30/11/2016","2/12/2016","3/12/2016","5/12/2016","6/12/2016","8/12/2016","9/12/2016"),format= "%d/%m/%Y"),
                 drug=c(2,1,2,2,1,2,1,2,2,1,2,1,2,1,2,1,1),
                 score=c(3,4,4,4,4,4,3,4,3,3,4,5,1,4,4,2,2))

3 个答案:

答案 0 :(得分:4)

您可以使用dplyr来获取此信息:


创建数据

DbGeography

填写缺失的行(天)

解决这些问题的一种很好的方法是使隐式缺少明确缺失的观察}

df <- data.frame(
  ID=c("A","A","A","A","A","A","B","B","B","B","C","C","C","C","C","C","C"),
  date=as.Date(c("28/08/2016","29/08/2016","30/08/2016","2/09/2016","3/09/2016","4/09/2016","8/08/2016","9/08/2016","10/08/2016","11/08/2016","30/11/2016","2/12/2016","3/12/2016","5/12/2016","6/12/2016","8/12/2016","9/12/2016"),format= "%d/%m/%Y"),
  drug=c(2,1,2,2,1,2,1,2,2,1,2,1,2,1,2,1,1),
  score=c(3,4,4,4,4,4,3,4,3,3,4,5,1,4,4,2,2)
)

df

#>    ID       date drug score
#> 1   A 2016-08-28    2     3
#> 2   A 2016-08-29    1     4
#> 3   A 2016-08-30    2     4
#> 4   A 2016-09-02    2     4
#> 5   A 2016-09-03    1     4
#> 6   A 2016-09-04    2     4
#> 7   B 2016-08-08    1     3
#> 8   B 2016-08-09    2     4
#> 9   B 2016-08-10    2     3
#> 10  B 2016-08-11    1     3
#> 11  C 2016-11-30    2     4
#> 12  C 2016-12-02    1     5
#> 13  C 2016-12-03    2     1
#> 14  C 2016-12-05    1     4
#> 15  C 2016-12-06    2     4
#> 16  C 2016-12-08    1     2
#> 17  C 2016-12-09    1     2

分类天数

library(dplyr)
library(tidyr)

df1 <- df %>% 
  group_by(ID) %>% 
  complete(date = seq(min(date), max(date), by = "day"))

df1

#> Source: local data frame [22 x 4]
#> Groups: ID [3]
#> 
#> # A tibble: 22 x 4
#>        ID       date  drug score
#>    <fctr>     <date> <dbl> <dbl>
#>  1      A 2016-08-28     2     3
#>  2      A 2016-08-29     1     4
#>  3      A 2016-08-30     2     4
#>  4      A 2016-08-31    NA    NA
#>  5      A 2016-09-01    NA    NA
#>  6      A 2016-09-02     2     4
#>  7      A 2016-09-03     1     4
#>  8      A 2016-09-04     2     4
#>  9      B 2016-08-08     1     3
#> 10      B 2016-08-09     2     4
#> # ... with 12 more rows

按日期类型汇总

df2 <- df1 %>% group_by(ID) %>% mutate(day_of = drug == 1, day_before = (lead(drug) == 1 & day_of == FALSE), day_after = (lag(drug) == 1 & day_of == FALSE)) df2 #> Source: local data frame [22 x 7] #> Groups: ID [3] #> #> # A tibble: 22 x 7 #> ID date drug score day_of day_before day_after #> <fctr> <date> <dbl> <dbl> <lgl> <lgl> <lgl> #> 1 A 2016-08-28 2 3 FALSE TRUE NA #> 2 A 2016-08-29 1 4 TRUE FALSE FALSE #> 3 A 2016-08-30 2 4 FALSE NA TRUE #> 4 A 2016-08-31 NA NA NA NA FALSE #> 5 A 2016-09-01 NA NA NA FALSE NA #> 6 A 2016-09-02 2 4 FALSE TRUE NA #> 7 A 2016-09-03 1 4 TRUE FALSE FALSE #> 8 A 2016-09-04 2 4 FALSE NA TRUE #> 9 B 2016-08-08 1 3 TRUE FALSE FALSE #> 10 B 2016-08-09 2 4 FALSE FALSE TRUE #> # ... with 12 more rows 将一个函数(dplyr::mutate_at)应用于funs()中选择的所有列。 vars()在操作某些选定列时的操作方式相同,但不是更改完整数据集的值,而是将其减少为每组一行。可以阅读有关m tidyr::completemutate和特殊summarise版本的更多信息。

summarise_at

答案 1 :(得分:1)

使用[size]及其data[3][3]data[2][2]函数的可能性如下:

data[m-1][n-1]

答案 2 :(得分:1)

我更喜欢使用时间序列包(如class Object1(models.Model): id_users = models.PositiveIntegerField(blank=True) class Object2(models.Model): id_object1 = models.FloatField() sth = models.FloatField() )来执行此类任务。

foreign key