根据日期

时间:2016-08-23 19:02:00

标签: r dplyr summarize

我是一个R菜鸟,并尝试对数据集执行摘要,该数据集总计了该ID的类型“B”事件之间发生的每个ID的事件类型数。以下是一个示例:

id <- c('1', '1', '1', '2', '2', '2', '3', '3', '3', '3')
type <- c('A', 'A', 'B', 'A', 'B', 'C', 'A', 'B', 'C', 'B')
datestamp <- as.Date(c('2016-06-20','2016-07-16','2016-08-14','2016-07-17'
                       ,'2016-07-18','2016-07-19','2016-07-16','2016-07-19'
                       , '2016-07-21','2016-08-20'))
df <- data.frame(id, type, datestamp)

产生:

> df
   id type  datestamp
1   1    A 2016-06-20
2   1    A 2016-07-16
3   1    B 2016-08-14
4   2    A 2016-07-17
5   2    B 2016-07-18
6   2    C 2016-07-19
7   3    A 2016-07-16
8   3    B 2016-07-19
9   3    C 2016-07-21
10  3    B 2016-08-20

每当发生事件'B'时,我想知道在该B事件之前发生的每种事件类型的数量,但是在该ID之后的任何其他B事件之后。 我想最终得到的是这样一个表:

  id type B_instance count
1  1    A          1     2
2  2    A          1     1
3  3    A          1     1
4  3    C          2     1

在研究中,这个问题最接近:summarizing a field based on the value of another field in dplyr

我一直在尝试做这项工作:

  df2 <- df %>%
  group_by(id, type) %>%
  summarize(count = count(id[which(datestamp < datestamp[type =='B'])])) %>%
  filter(type != 'B')

但是它出错了(同样,即使它有效,它也没有考虑同一ID中的2'B'事件,比如id = 3)

2 个答案:

答案 0 :(得分:1)

以下是使用data.table的选项。我们将'data.frame'转换为'data.table'(setDT(df),按'id'分组,我们得到max位置的序列,其中'type'是'B',找到行索引(.I),提取该列($V1)。然后,我们对数据集(df[i1])进行子集化,删除'type'为'B'的行,按'分组' id','type'和'type'的rleid,我们将行数作为'count'。

library(data.table)
i1 <- setDT(df)[, .I[seq(max(which(type=="B")))] , by = id]$V1
df[i1][type!="B"][,  .(count = .N), .(id, type, B_instance = rleid(type))]
#   id type B_instance count
#1:  1    A        1     2
#2:  2    A        1     1
#3:  3    A        1     1
#4:  3    C        2     1

答案 1 :(得分:0)

您可以cumsum使用B_instance创建新的组变量cumsum(type == "B"),然后过滤掉落在最后一个B后面的类型以及B类本身,因为它们会不计算在内。然后使用countidB_instancetype计算组的出现次数。

df %>% 
       group_by(id) %>% 
       # create B_instance using cumsum on the type == "B" condition
       mutate(B_instance = cumsum(type == "B") + 1) %>%    
       # filter out rows with type behind the last B and all B types                 
       filter(B_instance < max(B_instance), type != "B") %>% 
       # count the occurrences of type grouped by id and B_instance
       count(id, type, B_instance) 

# Source: local data frame [4 x 4]
# Groups: id, type [?]

#       id   type B_instance     n
#   <fctr> <fctr>      <dbl> <int>
# 1      1      A          1     2
# 2      2      A          1     1
# 3      3      A          1     1
# 4      3      C          2     1