Appendiks a: Små nyttige værktøjer

Dette appendiks indeholder små guides, der kan være nyttige for historikeren. De knytter sig ikke til noget specifikt kapitel i denne bog, men retter sig derimod især imod workflows, der kan assistere i mange forskellige kontekster.

Hvordan strukturerer jeg arbejdet med længere tekststykker?

Hvis vi arbejder med serielle tekstdata (mange stykker tekst), kan der være mange sammenhænge, hvor det er upraktisk at inputte rå-tekst direkte i en tabel. Det kan f.eks. være, hvis teksten er lang eller indeholder linjeskift. Excel håndterer fint korte tekstbidder, men er ikke bygget til prosa.

I sådan en situation kan man lade tekst-data leve i en mappe (her omtalt som “Tekster/”). Det giver bedst mening at have teksterne i individuelle .txt-filer. Dette format er et universelt brugt tekstformat, der dog ikke indeholder nogen form for formattering (i modsætning til f.eks. .docx eller .rtf).

Her antages det, at du har dine tekstfiler i en data-mappe, der ligger i samme projektmappe som dit script. Hvis mappen ligger et andet sted, skal du pege stierne imod det sted, hvor denne mappe bor.

Det forudsættes også, at dine tekstfiler er navngivet systematisk. Her opereres med et format, hvor vi navngiver vores tekstfiler efter et ID tildelt i et excel-ark, der indeholder metadata om hver tekst. Findes der en observation, der er tildelt ID 80003 i vores metadata-tabel, svarer den altså til en fil i vores mappe, der bærer navnet 80003.txt.

library(tidyverse)
library(readxl)

Vi starter med at hente .txt-filerne ind:

# Lav en liste over filerne i mappen data/Tekster/ - eller en anden sti, hvis dine filer bor et andet sted
fil_liste <- list.files(path = "data/Tekster/", 
                        pattern = "*.txt", 
                        full.names = TRUE)

# Hent filerne fra listen ind i en dataframe og navngiv kolonnen med indholdet "Text"
Tekstfiler <- data.frame(
  files = sapply(fil_liste, 
                 FUN = function(x)readChar(x, 
                                           file.info(x)$size)), 
  stringsAsFactors=FALSE)
Tekstfiler <- rename(Tekstfiler, Text = files)

# Rekonstruer et ID fra filnavnet
Tekstfiler$ID <- rownames(Tekstfiler)
Tekstfiler$ID <- str_remove_all(Tekstfiler$ID, "\\D")
Tekstfiler$ID <- as.character(Tekstfiler$ID)

Tekstfiler$Text
[1] "Her er min tekst nummer 1."                            
[2] "Her er min tekst nummer 2."                            
[3] "Her er min tekst nummer 3.\n\nDen er skrevet af Bodil!"

Vi loader derefter metadataene. Her skal du selvfølgelig loade den fil, hvis navn matcher navnet på din tabel med metadata.

metadata <- read_excel("data/Meta_data.xlsx") %>% 
  mutate(ID = as.character(ID))

metadata
# A tibble: 3 × 5
  ID    Resume     Afsender Dato       mere_metadata          
  <chr> <chr>      <chr>    <chr>      <chr>                  
1 80002 Kilde om x John     01/12/1898 noget om noget         
2 80003 kilde om y Per      02/03/1799 noget om det samme     
3 80004 Kilde om y Bodil    02/03/1799 noget om en tredje ting

Denne tabel indeholder alt vores metadata, men mangler selve teksterne. Nu skaber vi selve datasættet ved at joine de indlæste tekstfiler og metadata.

df <- Tekstfiler %>% 
  left_join(metadata)
df
                                                    Text    ID     Resume
1                             Her er min tekst nummer 1. 80002 Kilde om x
2                             Her er min tekst nummer 2. 80003 kilde om y
3 Her er min tekst nummer 3.\n\nDen er skrevet af Bodil! 80004 Kilde om y
  Afsender       Dato           mere_metadata
1     John 01/12/1898          noget om noget
2      Per 02/03/1799      noget om det samme
3    Bodil 02/03/1799 noget om en tredje ting

Voila! Nu er datasættet klar til, at vi kan arbejde med teksten i R. Du kan også eksportere det, hvis du hellere vil lave din analyse i noget andet software.

OCR-scanning med Tesseract

Med pakken Tesseract er det muligt at OCR-scanne i R. OCR-scanning virker kun på trykt tekst. Der findes metoder til at OCR-scanne trykte gotiske tekster, men det er en mere besværlig procedure i R og bliver ikke dækket her. Generelt vil jeg anbefale Transkribus til det foretagende. Her kigger vi derfor udelukkende på latinske bogstaver. Vi starter med at loade tesseract-pakken.

library(tesseract)

Ved første kørsel af Tesseract installeres sprogdata. Den installerer dog ikke dansk. Så det skal vi også gøre.

tesseract_download("dan")
[1] "/Users/johanheinsen/Library/Application Support/tesseract5/tessdata/dan.traineddata"

Herefter definerer vi, hvilket sprog vi vil køre med.

dansk <- tesseract("dan")

Lad os prøve at teste med en side fra Rigsarkivets scanning af Kancelliets brevbøger.

test_side <- ocr("https://ao.sa.dk/ao/data.ashx?bid=40551295", engine = dansk)
test_side
[1] "1660 27\n12. jan. (Kbh.) Albertus Matthisen, kongens bygmester, fik befaling til\ni Kastellet til soldatesken at lade opsætte en corps de garde foruden\ndem, som nu er der, så og at forfærdige de gamle så vel som batteriet.\nSjT, 35, 595. (Tr.: KD, V, 691). K.\n12. jan. (Kbh.) Borgmestre og råd i Kbh. fik brev om at tilholde tøm-\nmerlavet i staden straks uden forsømmelse til fæstningen at forfærdige\net parti fjælekister. På det, de des hastigere kan blive færdige, skal de\ngøre den anordning, at hver 2 mestre på en halv dag skaffer færdig 3 |\nkister, hvortil bygmesteren skal levere dem dæler og søm, så vel som\nvise dem stedet, hvor kisterne skal gøres færdige. Dermed etc. ST, 35,\n595. (Tr.: KD, V, 691). K. Indl. udat.\n12. jan. (Kbh.) Dæleskriver Bertel Marske fik brev om at lade mester\n[James] Robbins, skibsbygmester på Bremerholm, være følgagtig 300\nfyrredæler, som skal forbruges til at klæde på flåden med og til folkene\nat stå på, når skibene skal kølhales. SjT, 35, 596. K. Indl. 12. jan.\n1) Efter Indl.\n12. jan. (Kbh.) Dæleskriver Bertel Marske fik brev om mod bevis at\nlade Frederik Turesen, stadshopmand i staden, affølge 4/2 tylvt dæler\nog 8 små stykker norsk tømmer, som behøves til Vesterports kurtine.\nST, 35, 596. (Tr.: KD, V, 691-92). K. Indl. 12. jan.\n13.' jan. (Kbh.) Rentemestrene fik brev anlangende [brænde]ved og\npenge til Jens Juel til at udkopiere Cojectus manuskript. [] er af kon-\ngen befalet! at lade udskrive Cs manuskript. Adressaterne skal forskaf-\nfe ham fornødent ildebrændsel samt penge til at betale de studenter\nmed, som skal udskrive det. Dermed etc. SjT, 35, 594. Orig. i DKanc. B\n179P.\n1) K. er bagpå dat. 11. jan., hvilket svarer til nummereringen og dermed pla-\nceringen blandt K. 2) Se ovf., s. ??\n13. jan. (Kbh.) Dæleskriver Bertel Marske fik brev om at lade bygme-\nster Albertus Matthisen til de 2 batterier på de 2 gordiner, den ene ved\nKongens Have, den anden ved Den runde Kirke, være følgagtig 2 tylv-\nter og 4 træer 10 al. tømmer og 10 tylvter norske dæler, nok til bryst-\nværket på batterierne bag Løngangen 4 tylvter norske dæler. SjT, 35,\n596. K. Indl. udat.\n"

Resultatet er ikke perfekt, men det er heller ikke helt nonsens. Har du behov for mere korrekt tekst-data, kan det dog også her anbefales at springe ud i Transkribus.