【发布时间】:2023-03-15 08:43:01
【问题描述】:
我正在尝试根据以下玩具数据计算滚动总和:
structure(list(Tag = c("1", "1", "1", "1", "2", "2", "2", "2", "2",
"2"), ID = c("A", "A", "A", "B", "J", "J", "J", "A", "A", "A" ),
correctvis = c(1, 0, 1, 1, 1, 0, 1, 0, 1, 0)), row.names = c(NA,
-10L), groups = structure(list(ID = "A", Tag = "1",
.rows = structure(list(1:10), ptype = integer(0), class = c("vctrs_list_of",
"vctrs_vctr", "list"))), row.names = 1L, class = c("tbl_df", "tbl", "data.frame"), .drop = TRUE), class = c("grouped_df",
"tbl_df", "tbl", "data.frame"))
我已经使用data.table 和dplyr 这样做了:
test <- as.data.table(df)[,sums2 := frollsum(correctvis, 7), by = c("ID","Tag")]
test <- df %>%
group_by(ID, Tag) %>%
mutate(sums = roll_sum(correctvis, 7, align = "right", fill = NA))
两者的结果相同。
注意:实际上我的标签/ID 列表持续的时间要长得多,这就是为什么我使用 7 的窗口而不是更小的窗口。
问题:
尽管使用 group_by 和 by=,但 roll_sum 和 froll_sum 使用的窗口超出了组的边界。那就是:我想开始计数,好像每个分组之前的所有值 correctvis 都是 0(对于该分组)。
以下代码似乎尊重分组(基于tibbletime 包):
rolling_sum <- rollify(.f = sum, window = 7)
df <- df %>%
group_by(ID, Tag) %>%
mutate(sums2 = rolling_sum(correctvis))
但是,此代码不起作用,因为在某些情况下,每个特定分组的观察数少于 7 个,从而导致错误:
不能滚动应用的窗口大于 数据长度
我的问题:
- 我能否调整 dplyr/data.table 代码,使其在应用滚动总和时尊重我的分组?
或者
-
有没有一种方法可以让 rollify 代码适用于我的窗口大小。我的一个想法是使用 case_when :
rolling_sum <- rollify(.f = sum, window = case_when(n=1~1,n=2~2, etc.))
但我无法让它工作。
【问题讨论】:
-
确实如此!谢谢!
-
仔细检查后,
group_by和mutate(rollapply_sum =rollapplyr(correctvis, 7, sum, partial = TRUE)似乎部分有效。在大多数情况下,它可以满足我的需要。但是,有时 TAG/ID 组合会再次出现,但会被其他 TAG/ID 值打断。这应该被视为一个“新”组,但它继续从以前的事件中总结。我想我提供的 toydata 没有涵盖那种情况,我会看看我明天是否可以改变这个(或者可能到那时弄清楚)。 -
尝试通过检查 TAG/ID 何时更改来创建新的分组变量
标签: r dplyr data.table tibbletime