通过多个条件获得多列的滚动平均值,使用 dplyr 和 apply family

如何解决通过多个条件获得多列的滚动平均值,使用 dplyr 和 apply family

我正在对篮球数据进行分析。这就是我的数据集的样子(它的真正示例版本):

df<-data.frame(gmID = 1:20,H.Team = c("CLE","MIA","LAL","PHI","CLE","DET","CHI","DAL","UTA","PHO","POR","WAS","ORL","CHA","BOS","ATL","WAS"),A.Team = c("WAS","DEN","IND","HOU","SAC","OKC","MIL","DEN"),H.PTS = c(94,120,91,84,88,96,93,95,113,85,116,86,102,90,104,111),A.PTS = c(84,107,99,75,105,87,94,106,89,115,109,88),H.AST = c(22,25,24,18,21,26,16,19,27,22,23,25),A.AST = c(26,28,14,20,34,16))
df
   gmID H.Team A.Team H.PTS A.PTS H.AST A.AST
1     1    CLE    WAS    94    84    22    26
2     2    MIA    BOS   120   107    25    24
3     3    LAL    DAL    91    99    24    22
4     4    PHI    DEN    84    75    18    19
5     5    CLE    IND    88    90    18    22
6     6    DET    HOU    96   105    21    28
7     7    CHI    SAC    93    87    21    14
8     8    DAL    WAS    95    99    26    22
9     9    UTA    DAL   113    94    24    20
10   10    PHO    CLE    85    87    16    19
11   11    POR    LAL   116   106    19    21
12   12    WAS    OKC    86    84    27    18
13   13    ORL    DEN   102    89    24    22
14   14    CHA    IND    90    89    18    19
15   15    BOS    MIL    88    99    22    26
16   16    CHI    CLE    86   115    23    34
17   17    ATL    HOU   102   109    23    22
18   18    DAL    MIA   104    84    27    18
19   19    CLE    UTA    88    86    23    19
20   20    WAS    DEN   111    88    25    16

为了简化问题,我从原始数据集中选择了 20 行,仅选择了两对由主队 (H.) 和客场 (A.) 制作的比赛数据、得分 (PTS) 和助攻 (AST)(分别是我的数据中还有 50 对游戏统计数据)。 请注意,行按日期排序,因此不需要排列。

目标是对比赛结果进行预测(如果 H.Team 获胜,则为 1,如果 A.Team 获胜,则为 0),但是现在的数据形式没有用,因为一旦比赛结束就会报告统计数据.

因此,我们的想法是用前 n 个匹配的滚动平均值替换数据框的每个值。我将在我的工作中设置 n=7n=10,但现在这并不重要,因此为简化起见,我将设置 n=3

输出应如下所示:

   gmID H.Team A.Team   H.PTSav   A.PTSav  H.ASTav  A.ASTav
1     1    CLE    WAS        NA        NA       NA       NA
2     2    MIA    BOS        NA        NA       NA       NA
3     3    LAL    DAL        NA        NA       NA       NA
4     4    PHI    DEN        NA        NA       NA       NA
5     5    CLE    IND  94.00000        NA 22.00000       NA
6     6    DET    HOU        NA        NA       NA       NA
7     7    CHI    SAC        NA        NA       NA       NA
8     8    DAL    WAS  99.00000  84.00000 22.00000 26.00000
9     9    UTA    DAL        NA  97.00000       NA 24.00000
10   10    PHO    CLE        NA  91.00000       NA 20.00000
11   11    POR    LAL        NA  91.00000       NA 24.00000
12   12    WAS    OKC  91.50000        NA 24.00000       NA
13   13    ORL    DEN        NA  75.00000       NA 19.00000
14   14    CHA    IND        NA  90.00000       NA 22.00000
15   15    BOS    MIL 107.00000        NA 24.00000       NA
16   16    CHI    CLE  93.00000  89.66667 21.00000 19.66667
17   17    ATL    HOU        NA 105.00000       NA 28.00000
18   18    DAL    MIA  96.00000 120.00000 22.66667 25.00000
19   19    CLE    UTA  96.66667 113.00000 23.66667 24.00000
20   20    WAS    DEN  89.66667  82.00000 25.00000 20.50000

例如,对于打了 5 场比赛的团队 CLE,平均 PTS 值如下:

   gmID    avpts
1    1       NA    ---> NA
2    5 94.00000    ---> 94/1 
3   10 91.00000    ---> (94+88)/2 
4   16 89.66667    ---> (94+88+87)/3 
5   19 96.66667    ---> (88+87+115)/3 

我使用 dplyr 尤其是 zoo::rollaply 函数来获取上面显示的值,代码如下:

library(dplyr)
library(zoo)

sub<- df %>%
  filter(H.Team == "CLE" | A.Team == "CLE") %>%
  mutate(avpts = lag(rollapply(ifelse(H.Team == "CLE",H.PTS,A.PTS),width=3,FUN=mean,align="right",fill=NA,partial=1))) %>%
  select(gmID,avpts)
sub

我这样做只是为了一个团队和一个变量,但我可以很容易地为在 mutate() 中指定它的更多变量做到这一点,如下所示:

 mutate(avpts = lag(rollapply(ifelse(H.Team == "CLE",partial=1)),avast = lag(rollapply(ifelse(H.Team == "CLE",H.AST,A.AST),partial=1)))

问题是我应该为其他 50 个变量执行此操作,最重要的是我需要计算所有团队的值,而不仅仅是一个。 此外,我获得了一个具有正确值的列,但我不知道如何将它们替换为“正确”的位置。

我(部分)解决问题的想法是将上面的代码包装在一个函数中,然后使用 apply 系列中的另一个函数来获取所有团队的值,而不使用 for 循环。>

我编写了以下函数:

avstats<- function(team) {
  sub <- df %>%
    filter(.data$H.Team == !!team | .data$A.Team == !!team) %>%
    mutate(avpts = lag(rollapply(ifelse(H.Team == !!team,.data$H.PTS,.data$A.PTS),3,mean,partial=1))) %>%
    select(.data$gmID,.data$avpts)
}

最后,我通过这个小数据集中的团队列表使用了 lapply()

teams <- c("CLE","MIL")

lapply(teams,avstats)

而且这两个函数似乎一切正常。

但是我仍然希望回答两个主要问题

  • 如何在不为每个统计数据写一行的情况下获取所有其他变量的值? (即如何获得平均助攻、失误、ecc..)

  • 如何将生成的新平均值“组合”和“放在正确的位置”,使原始数据结构保持不变?

也许我应该修改我的函数 avstats 添加一些参数并因此使用另一个 apply() 函数,例如 mapply(),但我真的不知道该怎么做。

解决方法

你想要这个吗? (使用了来自 mean_runlibrary(runner))。

  • 您可以根据需要为任意数量的变量自动执行此过程。只需在 .cols
  • mutate(across... 参数中使用他们的名字
  • 要更改滚动窗口大小,只需根据选择更改 k 中的 mean_run
df %>% pivot_longer(!gmID,names_to = c("H_T",".value"),names_pattern = "(.+)\\.(.+)") %>%
  group_by(Team) %>%
  mutate(across(.cols = c(PTS,AST),~ runner::mean_run(x = .,k = 3,lag = 1),.names = '{.col}_av')) %>%
  pivot_wider(id_cols = gmID,names_from = H_T,names_glue = "{H_T}_{.value}",values_from = -c(gmID,H_T))

# A tibble: 20 x 11
    gmID H_Team A_Team H_PTS A_PTS H_AST A_AST H_PTS_av A_PTS_av H_AST_av A_AST_av
   <int> <chr>  <chr>  <dbl> <dbl> <dbl> <dbl>    <dbl>    <dbl>    <dbl>    <dbl>
 1     1 CLE    WAS       94    84    22    26     NA       NA       NA       NA  
 2     2 MIA    BOS      120   107    25    24     NA       NA       NA       NA  
 3     3 LAL    DAL       91    99    24    22     NA       NA       NA       NA  
 4     4 PHI    DEN       84    75    18    19     NA       NA       NA       NA  
 5     5 CLE    IND       88    90    18    22     94       NA       22       NA  
 6     6 DET    HOU       96   105    21    28     NA       NA       NA       NA  
 7     7 CHI    SAC       93    87    21    14     NA       NA       NA       NA  
 8     8 DAL    WAS       95    99    26    22     99       84       22       26  
 9     9 UTA    DAL      113    94    24    20     NA       97       NA       24  
10    10 PHO    CLE       85    87    16    19     NA       91       NA       20  
11    11 POR    LAL      116   106    19    21     NA       91       NA       24  
12    12 WAS    OKC       86    84    27    18     91.5     NA       24       NA  
13    13 ORL    DEN      102    89    24    22     NA       75       NA       19  
14    14 CHA    IND       90    89    18    19     NA       90       NA       22  
15    15 BOS    MIL       88    99    22    26    107       NA       24       NA  
16    16 CHI    CLE       86   115    23    34     93       89.7     21       19.7
17    17 ATL    HOU      102   109    23    22     NA      105       NA       28  
18    18 DAL    MIA      104    84    27    18     96      120       22.7     25  
19    19 CLE    UTA       88    86    23    19     96.7    113       23.7     24  
20    20 WAS    DEN      111    88    25    16     89.7     82       25       20.5

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-
参考1 参考2 解决方案 # 点击安装源 协议选择 http:// 路径填写 mirrors.aliyun.com/centos/8.3.2011/BaseOS/x86_64/os URL类型 软件库URL 其他路径 # 版本 7 mirrors.aliyun.com/centos/7/os/x86
报错1 [root@slave1 data_mocker]# kafka-console-consumer.sh --bootstrap-server slave1:9092 --topic topic_db [2023-12-19 18:31:12,770] WARN [Consumer clie
错误1 # 重写数据 hive (edu)&gt; insert overwrite table dwd_trade_cart_add_inc &gt; select data.id, &gt; data.user_id, &gt; data.course_id, &gt; date_format(
错误1 hive (edu)&gt; insert into huanhuan values(1,&#39;haoge&#39;); Query ID = root_20240110071417_fe1517ad-3607-41f4-bdcf-d00b98ac443e Total jobs = 1
报错1:执行到如下就不执行了,没有显示Successfully registered new MBean. [root@slave1 bin]# /usr/local/software/flume-1.9.0/bin/flume-ng agent -n a1 -c /usr/local/softwa
虚拟及没有启动任何服务器查看jps会显示jps,如果没有显示任何东西 [root@slave2 ~]# jps 9647 Jps 解决方案 # 进入/tmp查看 [root@slave1 dfs]# cd /tmp [root@slave1 tmp]# ll 总用量 48 drwxr-xr-x. 2
报错1 hive&gt; show databases; OK Failed with exception java.io.IOException:java.lang.RuntimeException: Error in configuring object Time taken: 0.474 se
报错1 [root@localhost ~]# vim -bash: vim: 未找到命令 安装vim yum -y install vim* # 查看是否安装成功 [root@hadoop01 hadoop]# rpm -qa |grep vim vim-X11-7.4.629-8.el7_9.x
修改hadoop配置 vi /usr/local/software/hadoop-2.9.2/etc/hadoop/yarn-site.xml # 添加如下 &lt;configuration&gt; &lt;property&gt; &lt;name&gt;yarn.nodemanager.res