0

I have a data base with plays of a football game in order of each play. I want to make a for loop that checks if the play before a field goal (one row up) was a timeout by the other team. I tried using [i - 1] below but not sure if that works as I get an error.

for (i in 1:nrow(example)) {
 if (example$field_goal_attempt[i] == 1 & example$timeout[i-1] == 1 & example$timeout_team[i-1] != 
example$posteam[i-1]) {
example$iced[i] == 1
} else {
 example$iced[i] == 0
}
}

example <- data.frame(game_id = c(10,10,10,10,10,13,13,13,13,13), 
field_goal_attempted = c(0,0,0,1,0,0,0,0,0,0), time_out = 
c(0,0,1,0,0,0,0,0,0,0), posteam = 
c("PIT","PIT","PIT","PIT","PIT","ATL","ATL","WAS","WAS","WAS"), timeout_team 
= c(NA, NA, "TEN",NA,NA,NA,NA,NA,NA,NA))

Show in New WindowClear OutputExpand/Collapse Output Error in if (example$field_goal_attempt[i] == 1 & example$timeout[i - : argument is of length zero

Jeff Henderson
  • 643
  • 6
  • 10
  • Start from 2: `2:nrow(example)` – SmokeyShakers Dec 11 '19 at 19:18
  • what is example$iced? the code says: if what is inside the "if-condition" is true print whether "example$iced[i] == 1" is true or not. Is that what you are trying to accomplish. You are just trying to evaluate that condition? – Jorge Lopez Dec 11 '19 at 19:20
  • 2:nrow(example) worked without error and works if only game is considered. but for multiple games in one data frame it comes back with : "Error in if (example$field_goal_attempt[i] == 1 & example$timeout[i - : missing value where TRUE/FALSE needed" – Jeff Henderson Dec 11 '19 at 19:34

1 Answers1

0

You can essentially look at the logic of your problem two ways:

  1. The for loop goes over the plays, as it does in your case - that is, i represents a play that is a field goal and i-1 represents the previous play. As suggested by @SmokeyShakers, you'd start from 2:
for (i in 2:nrow(example)) {
 if (example$field_goal_attempt[i] == 1 && example$timeout[i-1] == 1 && example$timeout_team[i-1] != example$posteam[i-1]) {
  example$iced[i] <- 1
 } else {
 example$iced[i] <- 0
 }
}

Note that I also suggest that you use && instead of &, as in the former case, the logical statements are evaluated one by one and stop at the first one that is FALSE, while the latter (&) evaluates all the parts of the if statement, even after it encounters a false one, thus wasting computational time. Additionally, as suggested by @Jorge in the comments, I also replaced the == with the assignment operator, <-, as it seems to me that you'd like to assign 1 or 0, not evaluate a logical statement whether example$iced[i] is equal to 1 or 0, respectively.

  1. The other way to look at this is to consider the potential timeout as represented by i, goal attempt is i+1, and your loop needs to terminate earlier by 1:
for (i in 1:(nrow(example)-1)) {
 if (example$field_goal_attempt[i+1] == 1 && example$timeout[i] == 1 && example$timeout_team[i] != example$posteam[i]) {
  example$iced[i+1] <- 1
 } else {
 example$iced[i+1] <- 0
 }
}
Brunox13
  • 775
  • 1
  • 7
  • 21
  • Regarding your comment above: *...but for multiple games in one data frame it comes back with : "Error in if (example$field_goal_attempt[i] == 1 & example$timeout[i - : missing value where TRUE/FALSE needed* - how do you store and then go over multiple games in one data frame? – Brunox13 Dec 11 '19 at 19:44
  • basically there are thousands of games in this df and once one ends the next just starts with the first play in the row below the prior games last play. – Jeff Henderson Dec 11 '19 at 19:48
  • Error in if (example$field_goal_attempt[i] == 1 && example$timeout[i - : missing value where TRUE/FALSE needed – Jeff Henderson Dec 11 '19 at 19:49
  • I see - is there any column in the data frame indicating which game it is? Could you post an example of what the important part of the data frame looks like? I would suggest that you add another condition to check that both lines `i` and `i-1` (or `i` and `i+1`, if you go the second route), come from the same game. – Brunox13 Dec 11 '19 at 19:54
  • yes, game_id is a numeric column for each game. I'm not as worried about adding another condition bc there cant be a game starting with a fg so I don't think that will be an issue. – Jeff Henderson Dec 11 '19 at 19:55
  • Sounds like your error is now related to this post: [Error in if/while (condition) {: missing Value where TRUE/FALSE needed](https://stackoverflow.com/questions/7355187/error-in-if-while-condition-missing-value-where-true-false-needed). Are you sure you don't have a typo in any of the column names and that all the columns/rows have values in them? – Brunox13 Dec 11 '19 at 20:03
  • OK added some example data of just five plays for two games (gameid 10 and 13) to give you an idea of what the relevant columns would look like – Jeff Henderson Dec 11 '19 at 20:03
  • mmm yes there are NA's as in the example. So i need to recode all NAs then? – Jeff Henderson Dec 11 '19 at 20:08
  • I'm looking at your example now and from what you posted, there seem to be a few typos: `example$field_goal_attempt` should be `example$field_goal_attempted` and `example$timeout` should be `example$time_out`. Additionally, yes - when you try running just `example$timeout_team[i-1] != example$posteam[i-1]`, it evaluates to `NA` and not `TRUE` or `FALSE`, so replacing the `NA`s with something else might help, too. When I make these changes, your code runs fine for me and I get a `1` in the `iced` column where it should be. – Brunox13 Dec 11 '19 at 20:19