Skabelsen af et søgeinterface

Forfattet af

Klart som blæk

Senest opdateret

31.12.2023

I arbejdet med vores data skabte vi allerede tidligt i processen et søgeinterface. Det blev til med henblik på tilgængeliggørelse af materialet, men tjente i processen også som vores egen fælles indgang til avisens tekster. Du kan udforske det endelige resultat i fanen “Søg i avisen.”

Interfacet er bygget i Shiny, der er et app-framework skabt af Posit. Oprindeligt er Shiny designet til R, men der findes pt. også en version til Python. En app i Shiny skal køre på en server, der kører en R-instans og en Shiny-app er reaktiv, forstået sådan, at den kan tage imod brugerinput (f.eks. et søgeord) og tilpasse output derefter (f.eks. ved at filtrere).

Nedenfor ses koden for den version af vores søgeinterface, der pt. er online.

library(shiny)
library(tidyverse)
library(DT)

df <- read_csv2("df_housekept.csv")
similarities <- read_csv2("Top_similarities_nv200.csv")

theme <- bslib::bs_theme(
  version = 5,
  bootswatch = "cosmo",
  primary = "red",
  font_scale = 1
)

ui <- fixedPage(
  title = "Aalborg Adresseavis Online (beta)",
  theme = theme,
  tabsetPanel(
    tabPanel("Søg i fritekst",
             titlePanel(title = div(img(src = "BETA_alt_2.png", height = 220))),
             width = 12,
             p("Velkommen til søgeinterfacet. Du kan søge på tværs af kolonner gennem søgelinjen til højre nedenfor. Det er også muligt at søge i specifikke kolonner ved hjælp af søgelinjen over kolonnen. Begge indgange tillader brug af Regex. Vil du søge på flere ord i direkte sammenhæng, er dette kun muligt via søgelinjen over den enkelte kolonne."),
             dataTableOutput("søg", width = "auto")
             ),
    tabPanel("Undersøg sprogbrug",
             titlePanel(title = div(img(src = "BETA_alt_2.png", height = 220))),
             width = 12,
             p("Find ords nære slægtninge, dvs. ord de optræder sammen med eller ord, der optræder i lignende sammenhænge. Søgningen kan bruges til at få en fornemmelse for diskursive tendenser og associationer. Ord kan være beslægtede både ved at optræde i sammen bidder af tekst, men også ved at optræde i lignende kontekster, uden nødvendigvis at gøre det sammen."),
             dataTableOutput("ordbrug", width = "auto"))
    )
)

server <- function(input, output, session) {
  output$søg = renderDataTable(
    df, 
    selection = "none",
    rownames = FALSE,
    escape = FALSE,
    filter = list(position = 'top', clear = FALSE), 
    options = list(
      columnDefs = c(list(list(targets = 4, width = '20%'))),
      language = list(search = "Søg: ",
                      thousands = ".",
                      info = "Viser _START_ til _END_ af _TOTAL_ tekster",
                      paginate = list(previous = 'Forrige', `next` = 'Næste', first = "Første", last = "Sidste" ),
                      infoFiltered = "(af i alt _MAX_)",
                      lengthMenu = "Vis: _MENU_",
                      infoEmpty = "Ingen hits. Beklager.",
                      emptyTable = "Ingen data fundet",
                      zeroRecords =  "Ingen hits",
                      filter = "Alt"
      ),
      search = list(regex = TRUE),
      pageLength = 5,
      searchHighlight = TRUE
    )
  )
  output$ordbrug = renderDataTable(
    similarities, 
    selection = "none",
    rownames = FALSE,
    escape = FALSE,
    filter = list(position = 'top', clear = FALSE), 
    options = list(
      columnDefs = list(list(targets = c(1, 2), searchable = FALSE)),
      search = list(regex = TRUE),
      list(pageLength = 15),
      language = list(search = "Søg: ",
                      thousands = ".",
                      info = "Viser _START_ til _END_ af _TOTAL_ tekster",
                      paginate = list(previous = 'Forrige', `next` = 'Næste', first = "Første", last = "Sidste" ),
                      infoFiltered = "(af i alt _MAX_)",
                      lengthMenu = "Vis: _MENU_",
                      infoEmpty = "Ingen hits. Beklager.",
                      emptyTable = "Ingen data fundet",
                      zeroRecords =  "Nøgleordet optræder for sjældent til, at konteksten kunne identificeres",
                      filter = "Alt"),
      searchCols = list(
                        list(search = "^(q|k)(u|v)inder$"),
                        NULL, NULL),
      dom = "tp"
      )
  )
}

shinyApp(ui, server)