我正在处理逐个棒球数据,并希望创建许多滚动平均值,其中一些是基于另一列的条件。数据有 600 万行,因此理想情况下该方法效率不会太低。我知道 dplyr 可能不是提高效率的最佳选择 - 但如果可能的话希望利用它。使用 32 GB 内存,所以我确实有一点回旋余地
这是数据示例:
mydata <- data.frame(pitch_type = c("FB", "SI", "CU", "FB", "CH", "FB", "FS", "SL", "FB", "CH"),
velocity = c(99, 97, 83, 97, 85, 101, 82, 84, 100, 83))
mydata
pitch_type velocity
1 FB 99
2 SI 97
3 CU 83
4 FB 97
5 CH 85
6 FB 101
7 FS 82
8 SL 84
9 FB 100
10 CH 83
在我的实际代码中,我有按投手分组、按时间顺序排序等的数据,但基本上我只想能够计算某些投球类型的滚动平均值。当音高类型不等于我想要计算的值时,我也无法获得 NA 值,我希望它恢复到之前的计算。
这是我正在寻找的示例。在这里,我想计算最后两次观察的平均速度,其中itch_type ==“FB”:
mydata_updated
pitch_type velocity l2_velo_fb
1 FB 99 NA
2 SI 97 NA
3 CU 83 NA
4 FB 97 98.00
5 CH 85 98.00
6 FB 101 99.00
7 FS 82 99.00
8 SL 84 99.00
9 FB 100 99.25
10 CH 83 99.25
看起来相对简单,但我一生都无法在网上找到与我正在寻找的类似的例子。在创建新列时,我有许多不同的列和条件需要完成,因此为每个过滤器创建新的数据框远非理想。
我确实找到了这个例子:
mutate(last1000FBvelo = ifelse(pitch_type %in% c("FB"),
rollapply(release_speed, 1000, mean, fill = NA, align = 'right', na.rm = TRUE), NA),
但我需要它恢复到之前的值,而不是 NA。此外,其中一些列的运行时间大约需要 30 分钟。
我还意识到有许多软件包可以计算滚动平均值(zoo、RccpRoll、slider、runner 是我遇到过的软件包)。很难说出什么对于我的用例来说是最有效的 - 假设其中一个可以实现条件过滤。
任何意见都将不胜感激
另外 - 并不重要,甚至没有必要,但如果有一个简单的选项来使用加权移动平均线,对最近的观察结果进行更多的权重,那就太棒了。
我不确定
99.25
,但这里有一个方法:
library(dplyr)
# library(zoo)
mydata %>%
mutate(
l2_velo_fb = if (first(pitch_type == "FB")) {
zoo::rollmeanr(velocity, 2, na.pad = TRUE)
} else rep(NA_real_, n()),
.by=pitch_type) |>
mutate(l2_velo_fb = zoo::na.locf(l2_velo_fb, na.rm = FALSE))
# pitch_type velocity l2_velo_fb
# 1 FB 99 NA
# 2 SI 97 NA
# 3 CU 83 NA
# 4 FB 97 98.0
# 5 CH 85 98.0
# 6 FB 101 99.0
# 7 FS 82 99.0
# 8 SL 84 99.0
# 9 FB 100 100.5
# 10 CH 83 100.5
if (...) zoo::rollmeanr(..) else NA
实际上只是一个很小的效率:如果您不想计算非FB
数据的滚动平均值,那么在if (.)
之前使用rollmeanr
可以让我们避免计算和丢弃结果。 (这也是我按pitch_type
分组的原因。)
我认为这是不正确的,因为一个简单的 2 宽滚动右均值是:
filter(mydata, pitch_type == "FB") %>%
mutate(vb=zoo::rollmeanr(velocity, 2, na.pad = TRUE))
# pitch_type velocity vb
# 1 FB 99 NA
# 2 FB 97 98.0
# 3 FB 101 99.0
# 4 FB 100 100.5
.by=
的使用基于dplyr_1.1.0
或更新版本。如果你年纪大了,那就改成
mydata %>%
group_by(pitch_type) %>%
mutate(
l2_velo_fb = ...
) %>%
ungroup() %>% ...