【问题标题】:Using a loop to create multiple data frames in R使用循环在 R 中创建多个数据帧
【发布时间】:2016-04-22 07:01:20
【问题描述】:

我有这个函数,它从 NBA 统计数据网站返回 JSON 数据的数据框。该函数接受某场比赛的比赛ID,并返回该比赛的半场得分数据帧。

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)
}

所以我想用这个函数做的是获取几个游戏 ID 的向量,并为每个游戏 ID 创建一个单独的数据框。例如:

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

我想采用向量“gameids”,并创建十四个数据帧。如果有人知道我将如何去做这将不胜感激!谢谢!

【问题讨论】:

    标签: r loops dataframe


    【解决方案1】:

    您可以通过如下设置函数将 data.frames 保存到列表中:

    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)
    

    请注意,我无法对此进行测试,因为 URL 似乎无法正常工作。我收到以下连接错误:

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

    【讨论】:

      【解决方案2】:

      添加到 Abdou 的答案中,您可以使用 assign() 函数创建动态数据框来保存每个游戏 ID 的结果

      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)
      }
      

      assign 函数将创建与游戏 IDS 数量相同的数据帧。它们被标记为 X1、X2、X3......Xn。希望这可以帮助。

      【讨论】:

      • fortunes::fortune(236): 唯一应该使用assign函数的人是那些完全理解为什么你不应该使用assign函数的人。
      【解决方案3】:

      使用 lapply(或 sapply)将函数应用于列表并将结果作为列表获取。因此,如果你得到一个包含多个游戏 id 的向量和一个执行你想做的函数的函数,你可以使用 lapply 来获取一个数据帧列表(因为你的函数返回 df)。

      我无法测试你的代码(你提供的函数有错误),但这样的东西应该可以工作:

      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 将包含您在 gameids 中提供的每个 ID 1 个数据帧。

      只需再次使用 lapply 进行额外的数据处理,包括将数据帧保存到磁盘。

      如果您必须处理大量数据,data.table 是一个不错的包。特别是 rbindlist 允许您在需要时将列表中包含的所有 dt (=df) 合并到一个列表中(拆分将执行相反的操作)。

      【讨论】:

        猜你喜欢
        • 2020-05-25
        • 2023-03-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-02-12
        • 2022-08-06
        • 2019-04-26
        • 1970-01-01
        相关资源
        最近更新 更多