Using a loop to create multiple data frames in R

38,380

Solution 1

You can save your data.frames into a list by setting up the function as follows:

getstats<- function(games){

  listofdfs <- list() #Create a list in which you intend to save your df's.

  for(i in 1:length(games)){ #Loop through the numbers of ID's instead of the ID's

    #You are going to use games[i] instead of i to get the ID
    url<- paste("http://stats.nba.com/stats/boxscoretraditionalv2?EndPeriod=10&
                EndRange=14400&GameID=",games[i],"&RangeType=2&Season=2015-16&SeasonType=
                Regular+Season&StartPeriod=1&StartRange=0000",sep = "")
    json_data<- fromJSON(paste(readLines(url), collapse=""))
    df<- data.frame(json_data$resultSets[1, "rowSet"])
    names(df)<-unlist(json_data$resultSets[1,"headers"])
    listofdfs[[i]] <- df # save your dataframes into the list
  }

  return(listofdfs) #Return the list of dataframes.
}

gameids<- as.character(c(0021500580:0021500593))
getstats(games = gameids)

Please note that I could not test this because the URLs do not seem to be working properly. I get the connection error below:

Error in file(con, "r") : cannot open the connection

Solution 2

Adding to Abdou's answer, you could create dynamic data frames to hold results from each gameID using the assign() function

for(i in 1:length(games)){ #Loop through the numbers of ID's instead of the ID's

#You are going to use games[i] instead of i to get the ID
url<- paste("http://stats.nba.com/stats/boxscoretraditionalv2?EndPeriod=10&
            EndRange=14400&GameID=",games[i],"&RangeType=2&Season=2015-16&SeasonType=
            Regular+Season&StartPeriod=1&StartRange=0000",sep = "")
json_data<- fromJSON(paste(readLines(url), collapse=""))
df<- data.frame(json_data$resultSets[1, "rowSet"])
names(df)<-unlist(json_data$resultSets[1,"headers"])

# create a data frame to hold results
assign(paste('X',i,sep=''),df)
}

The assign function will create data frames same as number of game IDS. They be labelled X1,X2,X3......Xn. Hope this helps.

Solution 3

Use lapply (or sapply) to apply a function to a list and get the results as a list. So if you get a vector of several game ids and a function that do what you want to do, you can use lapply to get a list of dataframe (as your function return df).

I haven't been able to test your code (I got an error with the function you provided), but something like this should work :

library(RJSONIO)
gameids<- as.character(c(0021500580:0021500593))
df_list <- lapply(gameids, getstats)

getstats<- function(game=x){
        url<- paste0("http://stats.nba.com/stats/boxscoretraditionalv2?EndPeriod=10&EndRange=14400&GameID=",
                     game,
                     "&RangeType=2&Season=2015-16&SeasonType=Regular+Season&StartPeriod=1&StartRange=0000")
        json_data<- fromJSON(paste(readLines(url), collapse=""))
        df<- data.frame(json_data$resultSets[1, "rowSet"])
        names(df)<-unlist(json_data$resultSets[1,"headers"])
        return(df)
}

df_list will contain 1 dataframe per Id you provided in gameids.

Just use lapply again for additionnal data processing, including saving the dataframes to disk.

data.table is a nice package if you have to deal with a ton of data. Especially rbindlist allows you to rbind all the dt (=df) contained in a list into a single one if needed (split will do the reverse).

Share:
38,380
intern
Author by

intern

Updated on July 05, 2022

Comments

  • intern
    intern almost 2 years

    I have this function that returns a data frame of JSON data from the NBA stats website. The function takes in the game ID of a certain game and returns a data frame of the halftime box score for that game.

    getstats<- function(game=x){
      for(i in game){
        url<- paste("http://stats.nba.com/stats/boxscoretraditionalv2?EndPeriod=10&
                    EndRange=14400&GameID=",i,"&RangeType=2&Season=2015-16&SeasonType=
                    Regular+Season&StartPeriod=1&StartRange=0000",sep = "")
        json_data<- fromJSON(paste(readLines(url), collapse=""))
        df<- data.frame(json_data$resultSets[1, "rowSet"])
        names(df)<-unlist(json_data$resultSets[1,"headers"])
      }
      return(df)
    }
    

    So what I would like to do with this function is take a vector of several game ID's and create a separate data frame for each one. For example:

    gameids<- as.character(c(0021500580:0021500593))
    

    I would want to take the vector "gameids", and create fourteen data frames. If anyone knew how I would go about doing this it would be greatly appreciated! Thanks!

  • Uwe
    Uwe almost 7 years
    fortunes::fortune(236): The only people who should use the assign function are those who fully understand why you should never use the assign function.