Ian
Ian

Reputation: 11

R warning in if statement

I'm trying to write a loop that runs through a dataframe and corrects incorrect values (EG comedies made by universal inflated their worldwide gross, multiplying it by 1.1 and comedies made by paramount inflated their domestic gross by $0.8) The dataframe specifies the movies, genre, studio, and the gross in different columns

for (i in 1:nrow(movie_data)) {
  movies <- movie_data[i,]
  if (distributor == "Universal") {
    if (genre == "Comedy") {
      movies$worldwide_gross <- movies$worldwide_gross / 1.1
    } 
  } else if (distributor == "Paramount") {
    if (genre == "Comedy") {
      movies$domestic_gross <- movies$domestic_gross - 0.8
    } else if (genre == "Drama") {
      movies$domestic_gross <- movies$domestic_gross - 1.2
    }
  }
}

what would be causing my error?

Upvotes: 1

Views: 50

Answers (2)

Ronak Shah
Ronak Shah

Reputation: 389155

As already mentioned in comments, there are obviously better and more optimised ways to do this. (case_when from dplyr, ifelse) but if you have to explicitly use a for loop, you can subset the row value with an index and then check for various conditions.

for (i in seq_len(nrow(movie_data))) {

   if (movie_data$distributor[i] == "Universal" & movie_data$genre[i] == "Comedy")
      movie_data$worldwide_gross[i] <- movies$worldwide_gross[i]/ 1.1
   else if (movie_data$distributor[i] == "Paramount") {
          if (movie_data$genre[i] == "Comedy") {
            movie_data$domestic_gross[i] <- movie_data$domestic_gross[i] - 0.8
      } else if (movie_data$genre[i] == "Drama") {
            movie_data$domestic_gross[i] <- movie_data$domestic_gross[i] - 1.2
     }
   }
 }

Upvotes: 0

PavoDive
PavoDive

Reputation: 6496

I think you don't need a for loop to achieve what you want. It's difficult to know, though, if you don't actually share a toy example of your data. dput(head(movies)) would do it.

With data.table the operation could be quite simple:

library(data.table)

setDT(movies)

movies[distributor == "Universal" & genre == "Comedy", 
       worldwide_gross := worldwide_gross / 1.1]

movies[distributor == "Paramount" & genre == "Comedy", 
       domestic_gross := domestic_gross - 0.8]

movies[genre == "Drama", 
       domestic_gross - 1.2]

Upvotes: 2

Related Questions