0

I have two data frames... one is a Prior Game data frame and the other consists of Match-ups.

I have a loop function and I want it to iterate through each row in the Match-ups data frame and execute the following tasks:

  • lookup and append data from the Prior Game data frame
  • run some calculations
  • keep the output of the calculations in the Match-ups data frame & write the output of these calculations to the Prior Game data frame

and then finally repeat these tasks for the next row in Match-ups.

The function currently is able to perform the lookup and calculations for the first set of games, but it doesn't look like it's writing the output back to the Prior Game data frame and moving to the next row.

How can I get it to append the output to the Prior Game data frame and then repeat for the next row? Thanks!

library(dplyr)
library(data.table)
library(tidyr)


Team_ID <- c(115)
Unique_ID <- c('x0_115','x0_110')
Team_ELO <- c(1500,   1500)
Points <-     c(2,-2)

Prior_Game <- data.frame(Team_ID, Unique_ID, Team_ELO, Points)

Matchup <- c('Game 1',   'Game 2',   'Game 3',   'Game 1',   'Game 2',   'Game 3')
Game_Cnt <- c(1,    2,    3,    1,    2,    3)
Unique_ID <- c('x1_115',    'x2_115',    'x3_115',    'x1_110',    'x2_110',    'x3_110')
Opp_Unique_ID <- c('x1_110',    'x2_110',    'x3_110','x1_115',    'x2_115',    'x3_115')
Prior_Gm_ID <- c('x0_115',    'x1_115',    'x2_115',    'x0_110',    'x1_110',    'x2_110')
Opp_Prior_Gm_ID <- c( 'x0_110',    'x1_110',    'x2_110',  'x0_115',    'x1_115',    'x2_115'  )
Team_ID <- c(115,    115,    115,    110,    110,    110)
Team_ELO <- c( 0,   0,   0,    0,   0,   0)
Opp_Team_ID <- c(110,110,110,115,115,115)
Opp_Team_ELO <- c(   0,   0,  0,     0,   0,   0)
Expected_win <- c(0,0,0,.0,.0,.0)
Result <-     c( 1,  1,   0,     0,   0,   1)
Opp_Result <-     c( 0,  0,   1,     1,   1,   0)
Points <-     c(0,   0,   0,      0,   0,   0)
Opp_Points <- c(0,   0,   0,     0,   0,   0)

Matchups <- data.frame(Matchup, Team_ID,  Opp_Team_ID, Unique_ID,Opp_Unique_ID,Prior_Gm_ID,Opp_Prior_Gm_ID,Game_Cnt, Team_ELO,   Opp_Team_ELO,  Expected_win,   Result, Opp_Result,Points, Opp_Points)


# the function

foo <- function(df_){
  for (i in 1:nrow(df_)) {
    df_[i,"Team_ELO"] =  Prior_Game[match(df_[i,"Prior_Gm_ID"],Prior_Game$Unique_ID),"Team_ELO"]# match the team and opp team to the lookup table to get the team's prior game's inital score and points
    df_[i,"Prior_Points"] =  Prior_Game[match(df_[i,"Prior_Gm_ID"],Prior_Game$Unique_ID),"Points"]
    df_[i,"Opp_Team_ELO"] =  Prior_Game[match(df_[i,"Opp_Prior_Gm_ID"],Prior_Game$Unique_ID),"Team_ELO"]
    df_[i,"Opp_Prior_Points"] =  Prior_Game[match(df_[i,"Opp_Prior_Gm_ID"],Prior_Game$Unique_ID),"Points"]

    df_[i,"Team_ELO"] =  df_[i,"Team_ELO"]+df_[i,"Prior_Points"] # compute each team's ELO going into the game - based on the team's inital score and points from their previous game
    df_[i,"Opp_Team_ELO"] =  df_[i,"Opp_Team_ELO"]+df_[i,"Opp_Prior_Points"]

    df_[i,"Expected_win"] = 1-(1/(1+10**((df_[i,"Team_ELO"] - df_[i,"Opp_Team_ELO"])/400))) # once we have the lookup and the ELO going into the game, we can calculate the expected win and points awarded
    df_[i,"Points"] = 4*(df_[i,"Result"] - df_[i,"Expected_win"])
    df_[i,"Opp_Points"] = 4*(df_[i,"Opp_Result"] - (1-df_[i,"Expected_win"]))

    Prior_Game = rbind(Prior_Game,data.frame(Team_ID=df_[i,"Team_ID"],Unique_ID=df_[i,"Unique_ID"],Team_ELO=df_[i,"Team_ELO"],Points=df_[i,"Points"])) # write the output for this row to the "Prior Game" table
  }
  return(df_)
}

Matchups<-data.frame(Matchups %>%
                    group_by(Matchup) %>%
                    do(foo(data.frame(.))))
Dgamelin
  • 83
  • 7

1 Answers1

1

At a glance, it appears as though your function is only returning df_, not the Prior_Game dataframe. You could: 1) have the function return both (as elements in a list) or 2) update the Prior_Game dataframe within each loop using the double arrow <<- assignment operator, which will define things outside of a for loop. (see here for more info on the double assigment arrow).

filups21
  • 1,611
  • 1
  • 19
  • 22
  • Tried the <<- route and it seems to do what I needed. Thanks! Will need to explore this a bit more to fully understand how it's working. – Dgamelin Aug 24 '19 at 02:21