【问题标题】:Creating a dataframe from a scraped character vector从抓取的字符向量创建数据框
【发布时间】:2017-12-08 06:09:54
【问题描述】:

我正在尝试创建一个包含以下列的数据框:名字、姓氏、政党、州、会员 ID。这是我的代码

library('rvest')

candidate_url <- 'https://www.congress.gov/help/field-values/member-bioguide-ids'
candidate_page <- read_html(candidate_url)
candidate_nodes <- html_nodes(candidate_page, 'table')
candidate_list <- html_text(candidate_nodes)

我的主要问题是获取成员 ID。示例 ID 为 A000009。当我使用 gsub 函数时,我在这个例子中失去了前导 A。 A 来自该候选人的姓氏 (Abercrombie),但我不知道如何将 A 添加回会员 ID。当然,如果有更好的方法,我愿意接受任何建议。

【问题讨论】:

    标签: r web-scraping html-parsing rvest


    【解决方案1】:

    试试这个。我已对此进行了更新,以包括分离不同的字段。

    library('rvest')
    library('dplyr')
    library('tidyr')
    
    candidate_url <- 'https://www.congress.gov/help/field-values/member-bioguide-ids'
    candidate_page <- read_html(candidate_url)
    candidate_nodes <- html_nodes(candidate_page, 'table')
    df.candidates <- as.data.frame(html_table(candidate_nodes, header = TRUE, fill = TRUE), stringsAsFactors = FALSE)
    df.candidates <- df.candidates[!is.na(df.candidates$Member),]
    
    df.candidates <- df.candidates %>%
                     mutate(Party.State = gsub("[\\(\\)]", "", regmatches(Member, gregexpr("\\(.*?\\)", Member))[[1]])) %>%
                     separate(Party.State, into = c("Party","State"), sep = " - ") %>%
                     mutate(Full.name = trimws(regmatches(df.candidates$Member, regexpr("^[^\\(]+", df.candidates$Member)))) %>%
                     separate(Full.name, into = c("Last.Name","First.Name","Suffix"), sep = ",", fill = "right") %>%
                     select(First.Name, Last.Name, Suffix, Party, State, Member.ID)
    

    【讨论】:

      【解决方案2】:

      既然您有一个 HTML 表格,请使用 html_table 将其提取到 data.frame。您需要fill = TRUE,因为该表在每个条目之间插入了额外的空行,之后您可以使用tidyr::drop_na 轻松删除这些行。

      library(tidyverse)
      library(rvest)
      
      page <- 'https://www.congress.gov/help/field-values/member-bioguide-ids' %>% 
          read_html()
      
      members <- page %>% 
          html_node('table') %>% 
          html_table(fill = TRUE) %>% 
          set_names('member', 'bioguide') %>% 
          drop_na(member) %>%    # remove empty rows inserted in the table
          tbl_df()    # for printing
      
      members
      #> # A tibble: 2,243 x 2
      #>                                             member bioguide
      #>  *                                           <chr>    <chr>
      #>  1       Abdnor, James (Republican - South Dakota)  A000009
      #>  2         Abercrombie, Neil (Democratic - Hawaii)  A000014
      #>  3     Abourezk, James (Democratic - South Dakota)  A000017
      #>  4     Abraham, Ralph Lee (Republican - Louisiana)  A000374
      #>  5        Abraham, Spencer (Republican - Michigan)  A000355
      #>  6         Abzug, Bella S. (Democratic - New York)  A000018
      #>  7 Acevedo-Vila, Anibal (Democratic - Puerto Rico)  A000359
      #>  8       Ackerman, Gary L. (Democratic - New York)  A000022
      #>  9    Adams, Alma S. (Democratic - North Carolina)  A000370
      #> 10          Adams, Brock (Democratic - Washington)  A000031
      #> # ... with 2,233 more rows
      

      如果您愿意,可以进一步提取member 列。

      还有许多其他有用的数据来源,其中一些将其与其他有用的变量相关联。 This one 结构合理并定期更新。

      【讨论】:

      • 我试过这个,但它删除了一半的成员。应该有 4000+,但是当我们使用 html_table 时,它​​会减半。我不知道为什么会这样,所以我正在尝试其他方法。
      • 不应该有4000+;该数字被空行夸大了。
      • 但如果你真的想要历史生物指南,你真正需要的是members &lt;- read.csv('https://theunitedstates.io/congress-legislators/legislators-historical.csv', stringsAsFactors = FALSE)
      • 感谢您提供新资源。我不知道那件事。如果我使用您在 cmets 中发布的 read.csv 代码,它会在新候选人上任时继续更新吗?另外,您怎么知道所有的空白区域?我没看到
      • 这是有道理的。感谢您的帮助!
      【解决方案3】:

      这有点骇人听闻,但如果您想使用正则表达式提取变量,这里有一些指针。

      candidate_list <- unlist(candidate_list)
      
      ID <- regmatches(candidate_list, 
        gregexpr("[a-zA-Z]{1}[0-9]{6}", candidate_list))
      
      party_state <- regmatches(candidate_list, 
        gregexpr("(?<=\\()[^)]+(?=\\))", candidate_list, perl=TRUE))
      
      names_etc <- strsplit(candidate_list, "[a-zA-Z]{1}[0-9]{6}")
      
      names <- sapply(names_etc, function(x) sub(" \\([^)]*\\)", "", x))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-04-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-08-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多