根据日期对 dplyr 中的组进行条件汇总
Conditional summarize of groups in dplyr based on date
我是 R 菜鸟,正在尝试对数据集执行摘要,该数据集汇总了每个 ID 的事件类型数量,这些事件发生在该 ID 的 'B' 类型事件之间。这是一个示例来说明:
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 事件之后发生的每种事件类型的数量。
我想要结束的是 table 这样的:
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)
您可以使用 cumsum
通过执行 cumsum(type == "B")
创建新的组变量 B_instance
然后过滤掉落后于最后一个 B 的类型以及类型 B 本身,因为他们不会被计算在内。然后使用 count
来计算 id
, B_instance
和 type
.
组的出现次数
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
这是一个使用 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
我是 R 菜鸟,正在尝试对数据集执行摘要,该数据集汇总了每个 ID 的事件类型数量,这些事件发生在该 ID 的 'B' 类型事件之间。这是一个示例来说明:
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 事件之后发生的每种事件类型的数量。 我想要结束的是 table 这样的:
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)
您可以使用 cumsum
通过执行 cumsum(type == "B")
创建新的组变量 B_instance
然后过滤掉落后于最后一个 B 的类型以及类型 B 本身,因为他们不会被计算在内。然后使用 count
来计算 id
, B_instance
和 type
.
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
这是一个使用 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