Создание кадра данных из очищенного вектора символов

Я пытаюсь создать фрейм данных со столбцами: имя, фамилия, сторона, штат, идентификатор участника. Вот мой код

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)

Моя главная проблема - получение идентификаторов участников. Пример идентификатора - A000009. Когда я использую gsub Функция я теряю ведущий A в этом примере. A от фамилии этого кандидата (Abercrombie), но я не знаю, как добавить A обратно в идентификатор участника. Конечно, если есть лучший способ, я открыт для любых предложений.

3 ответа

Решение

Поскольку у вас есть таблица 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 колонка может быть дополнительно извлечена, если хотите.

Есть также много других полезных источников для этих данных, некоторые из которых коррелируют их с другими полезными переменными. Этот хорошо структурирован и регулярно обновляется.

Дайте это попробовать. Я обновил это, чтобы включить выделение различных полей.

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)

Это немного странно, но если вы хотите извлечь переменные с помощью регулярных выражений, вот несколько указателей.

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))
Другие вопросы по тегам