如何从组中找到连续的周数,但是从数据集中的最大日期开始计算?
说我有这个数据框:
id Week
1 A 2/06/2019
2 A 26/05/2019
3 A 19/05/2019
4 A 12/05/2019
5 A 5/05/2019
6 B 2/06/2019
7 B 26/05/2019
8 B 12/05/2019
9 B 5/05/2019
10 C 26/05/2019
11 C 19/05/2019
12 C 12/05/2019
13 D 2/06/2019
14 D 26/05/2019
15 D 19/05/2019
16 E 2/06/2019
17 E 19/05/2019
18 E 12/05/2019
19 E 5/05/2019
我想要的输出是:
id count
1: A 5
2: B 2
3: D 3
4: E 1
我目前正在将日期转换为要获取订购号的因子,并对照根据每个组中的行数创建的参考号。
library(data.table)
df <- structure(list(id = structure(c(1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L,
2L, 3L, 3L, 3L, 4L, 4L, 4L, 5L, 5L, 5L, 5L),
.Label = c("A", "B", "C", "D", "E"), class = "factor"),
Week = structure(c(3L, 4L, 2L, 1L, 5L, 3L, 4L, 1L, 5L, 4L, 2L, 1L, 3L, 4L, 2L, 3L, 2L, 1L, 5L),
.Label = c("12/05/2019", "19/05/2019", "2/06/2019", "26/05/2019", "5/05/2019"), class = "factor")),
class = "data.frame", row.names = c(NA, -19L))
dt <- data.table(df)
dt[, Week_no := as.factor(as.Date(Week, format = "%d/%m/%Y"))]
dt[, Week_no := factor(Week_no)]
dt[, Week_no := as.numeric(Week_no)]
max_no <- max(dt$Week_no)
dt[, Week_ref := max_no:(max_no - .N + 1), by = "id"]
dt[, Week_diff := Week_no - Week_ref]
dt[Week_diff == 0, list(count = .N), by = "id"]
答案 0 :(得分:1)
对dplyr
解决方案的道歉,但我认为使用data.table
可以更简洁地实现类似的方法。
library(dplyr)
df$Week = lubridate::dmy(df$Week)
df %>%
group_by(id) %>%
arrange(id, Week) %>%
# Assign group to each new streak
mutate(new_streak = cumsum(Week != lag(Week, default = 0) + 7)) %>%
add_count(id, new_streak) %>%
slice(n()) # Only keep last week
答案 1 :(得分:1)
这是执行此操作的一种方法:
dt <- dt[, Week := as.Date(Week, format = "%d/%m/%Y")]
ids_having_max <- dt[.(max(Week)), id, on = "Week"]
dt <- dt[.(ids_having_max), on = "id"
][order(-Week), .(count = sum(rleid(c(-7L, diff(Week))) == 1)), by = "id"]
将其分解为步骤:
我们将Week
保留为日期,因为它已经可以比较了,
您可以减去日期以获得时差。
然后我们获得整个表中包含最大日期的所有id
。
这是使用secondary indices。
我们再次使用二级索引来过滤掉先前结果 部分中的id
(dt[.(ids_having_max), on = "id"
部分)。
最后一帧很棘手。
我们按id
分组,并确保行按Week
降序排列。
那么逻辑如下。
连续几个星期后,
根据所选的排序,diff(Week)
始终为-7。
计算diff
会返回一个较短的向量,因为第一个结果是通过从第二个元素减去第一个输入元素来计算的,
因此我们在前面加上-7以确保它是rleid
输入中的第一个元素。
使用rleid
,我们将第一个-7分配为1,并保持1,直到看到与-7不同的值。
不同的方式意味着几周不再连续。
sum(rleid(c(-7L, diff(Week))) == 1)
将仅返回rleid
等于1的行数。
B
的最后一部分的示例:
-7, -14, -7
-7, -7, -14, -7
rleid
之后:1, 1, 2, 3
rleid == 1
答案 2 :(得分:0)
因此,我建议按如下所示将数据列的格式转换为显示周数"%W"
dt[, Week_no := format(as.Date(Week, format = "%d/%m/%Y"),"%W")]
然后找到每个id
值的唯一星期数
dt[,(length(unique(Week_no))),by="id"]
完全公开
我意识到,当我运行此命令时,我得到的表与您提供的表不同,因为R用给定年份的周数来计数周数。
如果这不能回答您的问题,请告诉我,我可以尝试更新