PDF:1つの列リストを複数の列のデータフレームに変換する方法は?-複数の列へのグループ内のサブグループ内の人々のリスト

pbstckvrflw

私は人々のリストを含む15近くのPDFを持っていますこのPDFは1列幅しかないため、純粋なリストです。しかし、何らかの方法でこれらのリストはネストされています(グループ内のサブグループ内のサブグループ...)。リスト内の各人の最初の番号(私の分析にとって非常に重要です)と同様の注文情報以外に数値データはありません。

このリストをPDFから取り出して、従来のデータフレームに変換する必要があります。

1つのPDFの構造の例を次に示します。

TERRITORY ONE
1. GROUP ONE
1. Name Surname
2. Name Surname
3. Name Surname
4. Name Surname
2. GROUP TWO
1. Name Surname
2. Name Surname
3. Name Surname
4. Name Surname
TERRITORY TWO
(...)

これは最初のPDFです:http//bocyl.jcyl.es/boletines/1983/04/02/pdf/BOCYL-D-02041983-1.pdf


!!! これらのドキュメントもWebページに保存されているので、HTML形式で:http//bocyl.jcyl.es/html/1983/04/02/html/BOCYL-D-02041983-1.doたぶん簡単に入手できます。 PDFからではなくそれらからのコンテンツ?


ご想像のとおり、これは次のとおりです(テリトリー2、3、4 ...、後続のサブグループ1、2、3、4、...など)。これは、PDFあたり600行近くになり、最新のPDFではそれ以上になります。

この構造例に従うデータフレームを作成する必要があります。

   PERSON    |    TERRITORY  |  GROUP  | POSITION IN LIST
Name Surname | TERRITORY ONE | GROUP 1 |         1
(...)
Name Surname | TERRITORY ONE | GROUP 2 |         4
(...)
Name Surname | TERRITORY TWO | GROUP 1 |         3

一列は一人でなければなりません

POSITION IN LISTName Surname特定の年(各PDFは1年間)、彼TERRITORY彼の登場した人の順序を参照する必要がありますGROUP

それはランキングのようなものであると考えてください。それは人の順序が重要です。PDF1(1年目)の人のほとんどがPDF2(2年目)、次にPDF3(3年目)などに再び表示されます。したがって、これらすべての背後にある1つの目的は、何人、誰が繰り返すかを知ることです。このリストでは毎年。

また、分析では、毎年繰り返すその人の位置を知ること、この人の進化を描くこと、またはこの人がX年後に消えるかどうかを知ることなどが重要です。

PS:私の英語を許してください、私の第一言語ではありません:(

フランシス・バートン

これは、PDFではなくWebページをスクレイピングし、1つのソースのみを使用することに基づいた、より完全な回答です。したがって、スクレイプする複数のWebページでまだテストされていません。ソースデータの追加のWebページがある場合は、以下のコードの上部にあるベクターにそれらを追加します。

@pbstckvrflwの演習として残しておくことができます!

これは大変な作業でしたが、幸運なことに、私はそれをやって、いろいろなことを学びながら楽しんでいました。

ただし、この規模のタスクは通常、SOの質問には適していないことに注意しください。解決策を自分で試してから、発見した問題について非常に具体的な質問をすることをお勧めします。

私が書いたコードを注意深く読み、各ステップで何が起こっているのかを理解してください。あなたが学ぶ必要があるかもしれない主なことはmap、それがリスト内のすべてのアイテムに関数を適用する方法についてです。mapネストされたリストを使用しているため、ここでは広く使用しています。いくつかの良い正規表現もあります。

完璧なコードにはほど遠いため、エラーや非効率が発生する可能性があります。その一部を繰り返し可能な関数に分解したほうがよいでしょう。そして、それは少し厄介ないくつかの中間オブジェクトを生成しますが、それはまさにその通りです。明確にするために、コードはブロックになっています。これは、物事が壊れるリスクを過度にかけずに、ブロックをより流動的なワークフローに統合する時間がないためです。

library(rvest)
library(stringr)
library(purrr)
library(dplyr)
library(tibble)
library(conflicted)
conflict_prefer("pluck", "purrr")

# you should add any further URLs to this vector
urls <- c("http://bocyl.jcyl.es/html/1983/04/02/html/BOCYL-D-02041983-1.do")

# scrape text from the relevant part of the webpage
# (assume that any additional URLs have the same structure)
text <- urls %>%
  map(., ~ {xml2::read_html(.) %>%
      rvest::html_nodes("#presentDocumentos p:not([class])") %>% 
      html_text})

# extract a manageable name from the URL and use it to name each text
names(text) <- urls %>% 
  str_extract_all(., pattern = "(?<=/)BOCYL.*(?=\\.do$)")

# do any manual fixes for errors in source data
text1 <- text %>% 
  map(., ~
  str_replace_all(., "PARTIDO COMUNISTA DE ESPAÑA PARTIDO COMUNISTA DE CASTILLA- LEON", "2. PARTIDO COMUNISTA DE ESPAÑA PARTIDO COMUNISTA DE CASTILLA- LEON"))

text2 <- text1 %>%
  map(., ~ 
        str_replace_all(., "(\\.)*(\\s)*$", "") %>% 
        str_replace_all(., "(\\s)+", " ") %>% 
        str_replace_all(., "^Suplente.*", "") %>% 
        str_c(., collapse = ";") %>% 
        str_split(., pattern = "JUNTA ELECTORAL DE ") %>% 
        map(., ~ tail(., -1) %>% 
              str_split(.,
                        pattern = ";(?=\\d{1,2}\\.\\s([:upper:]|\\s){2,})") %>% 
              set_names(str_to_title(map(., 1))) %>% 
              map(., ~ tail(., -1))
        )
  )


text3 <- text2 %>% 
  map(., ~
        map(., ~ 
              map(., ~ str_split(., pattern = ";(?=\\d{1,2}\\.\\s)") %>% 
                    set_names(map(., 1) %>% 
                                str_extract(., pattern = "(?<=\\d{1,2}\\.\\s)[:upper:].*")) %>% 
                    map(., ~ tail(., -1) %>% 
                          enframe(., name = "list_position", value = "person_name") %>% 
                          mutate_at(
                            vars("person_name"),
                            ~ str_extract_all(.,
                                              pattern = "(?<=\\d{1,2}\\.\\s)[:alpha:]+.*"))))))

text4 <- text3 %>% 
  map(., ~
        map(., ~ 
              map(., ~
                    map_df(., c, .id = "political_group"))))

text5 <- text4 %>% 
  map(., ~
        map(., ~ 
              map_df(., c, .id = "territory")))

# EXAMPLE
# To look at just the data frame produced from the first web page supplied
# (with columns rearranged as desired):
data_frame1 <- text5 %>% 
  pluck(1, 1) %>% 
  select(person_name, everything())
data_frame1

作成したGitHubリポジトリに最新のコードをプッシュしました質問に対するこの回答に満足している場合は、これを承認済みの回答としてチェックしてください。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

Related 関連記事

ホットタグ

アーカイブ