从剪切的字符向量创建数据框

时间:2017-07-04 17:36:59

标签: r web-scraping html-parsing rvest

我正在尝试创建一个包含以下列的数据框:名字,姓氏,聚会,州,会员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。当然,如果有更好的方式,我愿意接受任何建议。

3 个答案:

答案 0 :(得分: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)

答案 1 :(得分:1)

由于您有一个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结构合理,定期更新。

答案 2 :(得分:0)

这有点hackish,但如果你想使用正则表达式提取变量,这里有一些指示。

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