【问题标题】:Counting and storing a number of occurrences of one variable, based on another variable of a dataframe in R基于R中数据帧的另一个变量计算和存储一个变量的出现次数
【发布时间】:2020-03-24 13:25:28
【问题描述】:
Date         HomeTeam      AwayTeam        FTHG  FTAG FTR  
   <chr>      <chr>        <chr>          <dbl> <dbl> <chr>
 1 08/10/2018 Man United   Leicester          2     1 H    
 2 08/11/2018 Bournemouth  Cardiff            2     0 H    
 3 08/11/2018 Fulham       Crystal Palace     0     2 A    
 4 08/11/2018 Huddersfield Chelsea            0     3 A    
 5 08/11/2018 Newcastle    Tottenham          1     2 A    
 6 08/11/2018 Watford      Brighton           2     0 H    
 7 08/11/2018 Wolves       Everton            2     2 D    
 8 08/12/2018 Arsenal      Man City           0     2 A    
 9 08/12/2018 Liverpool    West Ham           4     0 H  

我正在尝试动态计算每个团队在 FTR 列('H'、'A'、'D')中可能出现的每个值的出现次数。目标是确定每支球队最近 10 场比赛的记录。联赛数据按特定日期过滤,因此球队可能在请求的日期没有打过 10 场比赛。然后,此信息(团队的 Last10 记录)将合并到包含团队统计数据的更大表格中。因此,我认为解决此问题的最简单方法是创建一个数据框/小标题,其中团队的名称在一列中,他们的 Last10 记录在第二列中。

我见过几个连续计数和按组计数的解决方案,但没有一个是迭代地执行它,有限制,并按我的需要存储它。结果应如下所示。

1 Man United 6-1-3
2 Leicester  2-3-5
3 Arsenal    4-5-1
4 Man City   8-1-1

【问题讨论】:

  • 这不是xtabs 的工作吗?无论是主场还是客场比赛,您都想要计数吗?
  • @RuiBarradas 是的。对于这篇文章,主客场比赛无关紧要。

标签: r function for-loop iteration func


【解决方案1】:

假设你的数据库在dfdata.frame,前面的代码产生一个data.frame,有四列:TeamsHAD,最后的结果匹配:

# Store the last 10 matches result of each team
# Check if there is a nicer way to obtain the names of all the teams
Last10 <- data.frame(Teams = names(table(rbind(df$HomeTeam, 
                                               df$AwayTeam))))
# Create empty columns to store results
Last10[,ncol(Last10)+c(1,2,3)] <- 0 
names(Last10) <- c("Teams","H", "D", "A")

MaxMatches <- 10 # Maximum number of last matches that would score
FilterDate <- df$Date[1:9] # Select which dates are taken into account
for (i in rev(which(df$Date %in% FilterDate))) { 
  # Go from the end date to the beginning
  # Check which teams have played
  teamindex <- which(Last10$Teams %in% df[i,c("HomeTeam","AwayTeam")])
  # Check if any of the teams have all the needed matches 
  teamscore <- rowSums(Last10[teamindex,c("H","D","A")])
  # If any teamscore is greater than the maximum number of matches
  # the scores should not be updated
  Last10$H[teamindex] <- Last10$H[teamindex] + 
    ifelse(teamscore < MaxMatches & df[i,"FTR"] == "H", 1, 0) 
  Last10$A[teamindex] <- Last10$A[teamindex] + 
    ifelse(teamscore < MaxMatches & df[i,"FTR"] == "A", 1, 0) 
  Last10$D[teamindex] <- Last10$D[teamindex] + 
    ifelse(teamscore < MaxMatches & df[i,"FTR"] == "D", 1, 0) 
}

如果您希望粘贴在一起的三列看起来像H-A-D,那么您可以使用:

Last10$results <- apply(Last10[,c("H","D","A")], 1, paste, collapse = "-")

【讨论】:

  • 我已经过滤了日期输入的原始数据框。如果有帮助,我有一个名为“Team_Names”的向量。
  • 另外,我一般不会看过去 10 场比赛。我正在查看每支球队的最后 10 场比赛。无论他们是主队还是客队。
  • 该代码一般不会查找最后 10 场比赛,它只会更新每支球队的 H、D 和 A 分数,如果这些分数之和小于 10。由于 for 循环来自end 到日期的开头,分数会更新为每支球队的最后 10 场比赛,其他比赛不考虑在内,因为分数总和超过 10。另外,如果您已经过滤了您的日期只需将for 循环更改为for (i in rev(1:nrow(df))),它将遍历您过滤的data.frame 的所有行
  • 您能否详细说明以下代码的作用? Last10$W[teamindex] 这会返回什么?
  • 我不知道Last10$W[teamindex] 会返回什么,因为没有W 列。但是,teamindex 只是每场比赛的主队和客队的Last10 data.frame 的行索引。我用它来更新只有在迭代器i所在的日期打过比赛的球队的分数H、A和D。
【解决方案2】:

也许以下内容可以满足问题的要求。
它使用xtabs 将感兴趣的列制成表格,然后将结果转换为类矩阵。

df2 <- reshape2::melt(df1[c(2, 3, 6)], id.vars = "FTR")[-2]
res <- xtabs(~ value + FTR, df2)
dimnames(res) <- unname(dimnames(res))
rm(df2)

head(res)
#               A D H
#Arsenal        1 0 0
#Bournemouth    0 0 1
#Brighton       0 0 1
#Cardiff        0 0 1
#Chelsea        1 0 0
#Crystal Palace 1 0 0

要将团队名称作为第一列的 data.frame,只需 cbind 行名称和矩阵。

res <- cbind.data.frame(Team_names = rownames(res), res)
rownames(res) <- NULL
head(res)
#      Team_names A D H
#1        Arsenal 1 0 0
#2    Bournemouth 0 0 1
#3       Brighton 0 0 1
#4        Cardiff 0 0 1
#5        Chelsea 1 0 0
#6 Crystal Palace 1 0 0

【讨论】:

  • 越来越近了。我从项目的另一部分的函数中提取了联赛统计数据,我知道这是正确的,因为我在 Excel 中手动验证了它。第一组是“res”的输出。第二个是应该的。
  • ADH 阿森纳 5 3 5 伯恩茅斯 5 2 7 布莱顿 3 3 8 伯恩利 5 3 6 卡迪夫 4 2 8 切尔西 4 4 5 水晶宫 6 3 5 埃弗顿 2 4 7 富勒姆 3 2 8 哈德斯菲尔德 6 4 4莱斯特 5 3 6 利物浦 5 3 5 曼城 4 2 8 曼联 4 4 6 纽卡斯尔 7 3 4 南安普顿 3 6 5 托特纳姆 9 0 4 沃特福德 5 2 7 西汉姆 6 3 5 狼队 5 4 5
  • 球队纪录 1 阿森纳 8-2-3 2 伯恩茅斯 6-6-2 3 布莱顿 5-6-3 4 伯恩利 2-9-3 5 卡迪夫 3-9-2 6 切尔西 8-1 -4 7 水晶宫 3-8-3 8 埃弗顿 6-3-4 9 富勒姆 2-9-2 10 哈德斯菲尔德 2-8-4 11 莱斯特 6-5-3 12 利物浦 10-0-3 13 曼城 12- 0-2 14 曼联 6-4-4 15 纽卡斯尔 3-8-3 16 南安普顿 1-7-6 17 热刺 10-3-0 18 沃特福德 6-6-2 19 西汉姆联 4-7-3 20 狼队 4 -6-4
  • 这是我在 SO 上的第一篇文章,所以如果有更好的方法来发布这些数据,请通知我。
猜你喜欢
  • 2018-12-03
  • 1970-01-01
  • 2021-03-15
  • 2022-01-03
  • 1970-01-01
  • 1970-01-01
  • 2021-02-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多