2017-07-04 6 views
1

Ich versuche, einen Datenrahmen zu erstellen, der die Spalten enthält: Vorname, Nachname, Party, Bundesland, Mitglieds-ID. Hier ist mein CodeErstellen eines Datenrahmens aus einem geschabten Zeichenvektor

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) 

Mein Hauptproblem ist die Mitglieder IDs zu bekommen. Eine Beispiel-ID ist A000009. Wenn ich die gsub Funktion verwende, verliere ich die führende A in diesem Beispiel. Das A stammt vom Nachnamen dieses Kandidaten (Abercrombie), aber ich weiß nicht, wie ich das A wieder in die Mitglieds-ID einfügen kann. Natürlich, wenn es einen besseren Weg gibt, bin ich offen für irgendwelche Vorschläge.

Antwort

1

Da Sie eine HTML-Tabelle haben, verwenden html_table es zu einem data.frame zu extrahieren. Sie benötigen fill = TRUE, da die Tabelle zusätzliche leere Zeilen zwischen den einzelnen Einträgen enthält, die Sie anschließend problemlos mit tidyr::drop_na löschen können.

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 

Die member Säule weiter extrahiert werden konnte, wenn man so will.

Es gibt auch viele andere nützliche Quellen für diese Daten, von denen einige mit anderen nützlichen Variablen korrelieren. This one ist gut strukturiert und regelmäßig aktualisiert.

+0

Ich versuchte dies, aber es entfernt die Hälfte der Mitglieder. Es sollte 4000+ sein, aber wenn wir html_table verwenden, wird es halbiert. Ich konnte nicht herausfinden, warum das passiert ist, also versuche ich andere Methoden. – Jordan

+0

Es sollte nicht 4000+ sein; Diese Zahl wird durch die leeren Zeilen aufgebläht. – alistaire

+0

Aber wenn Sie wirklich historische Bioguides wollen, brauchen Sie nur 'members <- read.csv ('https://theunitedstates.io/congress-legislators/legislators-historical.csv', stringsAsFactors = FALSE)' – alistaire

1

Probieren Sie es aus. Ich habe dies aktualisiert, um die verschiedenen Felder zu trennen.

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

Dies ist ein bisschen hackish, aber wenn Sie die Variablen mithilfe von Regex extrahieren möchten, hier sind ein paar Hinweise.

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