【问题标题】:Creating a for loop from multiple links to create one table, using ESPN links for multiple seasons/years从多个链接创建一个 for 循环以创建一个表,使用多个季节/年份的 ESPN 链接
【发布时间】:2018-07-14 00:44:47
【问题描述】:

我有以下链接,成功抓取,我想创建一个for 循环。我正在抓取的表格分布在 3 页上,因此 whip_2018awhip_2018bwhip_2018c 链接向量:

library(tidyverse)
library(rvest)

whip_2018a <- "http://www.espn.com/mlb/stats/pitching/_/order/false"
whip_2018b <- "http://www.espn.com/mlb/stats/pitching/_/count/41/qualified/true/order/false"
whip_2018c <- "http://www.espn.com/mlb/stats/pitching/_/count/81/qualified/true/order/false"

这些链接是 2018 年的季节,但我的链接可以追溯到 2005 年。如何将以下代码转换为 for 循环,以考虑多个页面链接和多年/季节?强>

# Scraping 2018 tables - there are multiple pages to the list
a2018 <- whip_2018a %>%
  read_html %>%
  html_node("#my-players-table > div > div.mod-content > table") %>%
  html_table(header = T)

b2018 <- whip_2018b %>%
  read_html %>%
  html_node("#my-players-table > div > div.mod-content > table") %>%
  html_table(header = T)

c2018 <- whip_2018c %>%
  read_html %>%
  html_node("#my-players-table > div > div.mod-content > table") %>%
  html_table(header = T)

# This creates the table for the 2018 season
whip_2018 <- rbind(a2018, b2018, c2018)

如果这不可能,我理解,但我的直觉告诉我,一些位置合适的 [i] 可以使这项工作发挥作用。供参考,2017的链接在这里(大多数季节至少有两个或三个链接):

whip_2017a <- "http://www.espn.com/mlb/stats/pitching/_/year/2017/order/false"
whip_2017b <- "http://www.espn.com/mlb/stats/pitching/_/year/2017/count/41/qualified/true/order/false")

WHIP 是 MLB 统计数据,因此是我的向量名称。

【问题讨论】:

    标签: r loops dplyr lapply rvest


    【解决方案1】:

    考虑在定义的函数中概括您的流程并传入年份参数。并循环遍历函数,将年份向量传入lapply,以便在末尾与do.call(rbind, ...)bind_rows 连接数据帧列表。

    get_whip_data <- function(yr_param) {
    
        # ASSIGN URLS
        whip_a <- paste0("http://www.espn.com/mlb/stats/pitching/_/year/", yr_param, "/order/false")
        whip_b <- paste0("http://www.espn.com/mlb/stats/pitching/_/year/", yr_param, "/count/41/qualified/true/order/false")
        whip_c <- paste0("http://www.espn.com/mlb/stats/pitching/_/year/", yr_param, "/count/81/order/false")
    
        # BUILD DATA FRAMES
        a_data <- whip_a %>%
          read_html %>%
          html_node("#my-players-table > div > div.mod-content > table") %>%
          html_table(header = T)
    
        b_data <- whip_b %>%
          read_html %>%
          html_node("#my-players-table > div > div.mod-content > table") %>%
          html_table(header = T)
    
        c_data <- whip_c %>%
          read_html %>%
          html_node("#my-players-table > div > div.mod-content > table") %>%
          html_table(header = T)
    
        # APPEND ALL
        yr_df <- rbind(a_data, b_data, c_data)   # OR do.call(rbind, list(a_data, b_data, c_data))
        yr_df$year <- yr_param
    
        return(yr_df)
    }
    
    df_list <- lapply(2005:2017, get_whip_data)
    
    final_df <- do.call(rbind, df_list)       # REQUIRES SAME COLUMNS ACROSS YEARS
    final_df <- dplyr::bind_rows(df_list)     # USE IF COLUMNS MAY DIFFER ACROSS YEARS
    

    如果您有可用的硬编码链接,请使用Map(包装到mapply)传递它们。这假定Map 逐元素迭代的所有参数长度相等。

    get_whip_data <- function(yr_param, whip_a, whip_b, whip_c) {
    
        # BUILD DATA FRAMES
        a_data <- whip_a %>%
          read_html %>%
          html_node("#my-players-table > div > div.mod-content > table") %>%
          html_table(header = T)
    
        b_data <- whip_b %>%
          read_html %>%
          html_node("#my-players-table > div > div.mod-content > table") %>%
          html_table(header = T)
    
        c_data <- whip_c %>%
          read_html %>%
          html_node("#my-players-table > div > div.mod-content > table") %>%
          html_table(header = T)
    
        # APPEND ALL
        yr_df <- rbind(a_data, b_data, c_data)
        yr_df$year <- yr_param
    
        return(yr_df)
    }
    
    df_list <- Map(get_whip_data, years_vec, a_urls_vec, b_urls_vec, c_urls_vec)
    
    final_df <- do.call(rbind, df_list)       # REQUIRES SAME COLUMNS ACROSS YEARS
    final_df <- dplyr::bind_rows(df_list)     # USE IF COLUMNS MAY DIFFER ACROSS YEARS
    

    【讨论】:

    • 你能定义“硬编码链接”吗?抱歉——我不是 R 的新手,但 R 几乎是我能流利使用的唯一语言。谢谢!
    • OHHH,“硬编码链接”是指我的所有链接都可以追溯到 2005 年吗?
    • 是的。第一个解决方案动态创建 URL。第二种解决方案读取先前分配的 URL。
    • 另一个问题 - 假设我想再拆分几次 URL,如下所示:paste0("http://www.espn.com/mlb/team/stats/", side, "/_/name/", team, "/year/", season, "/") - 每次我尝试运行它时,我都会收到错误消息。我在上面的函数中运行它,除了挑选球队、守备/击球和赛季
    • 您需要将这些其他向量作为附加参数传递到Map,粘贴在一起以构建 URL。
    猜你喜欢
    • 2016-11-28
    • 1970-01-01
    • 2021-09-02
    • 1970-01-01
    • 1970-01-01
    • 2014-08-12
    • 1970-01-01
    • 2021-12-01
    • 2018-07-30
    相关资源
    最近更新 更多