library(WikidataR)
library(tidyverse)
library(igraph)
library(visNetwork)
library(knitr)This project investigates the quality, content and completeness of information about literary influences on authors represented in Wikidata. In the network graph below, writers with five or more connections are shown, with the “influencers” coloured in purple and the “influenced” in orange. The size of each purple node is proportional to how often that author appears as an influence on another.
You can use the controls or scroll to zoom and drag to reposition. Click a node (writer) to highlight the immediate neighbourhood.
R libraries used in this post:
Interim Findings and Observations
A disclaimer and content warning: This is work in progress. I am not intending to claim that this data is a good reflection of the literary influence landscape, however this is defined1. Wikidata coverage of influence is patchy and poorly referenced, reflecting in part the organic, hobbiest and quite biased social knowledge representation of the Wikiverse.
The data extraction method to derive my “influence_data” dataset is shown below with accompanying code. A random sample of the data indicates we may be including some people better known for other occupations (e.g. singer, poet, actor, comedian) as the occupation can be multiple for any particular person. We also see anomolies where the influencer lived after the influenced (though Harold Bloom has posited this kind of paradoxical reverse influence!2). The data is also clearly biased toward northern hemisphere, English-speaking males.
Sample rows from the dataset (Q numbers are Wikidata entity IDs)
influence_data |> slice_sample(n=10) |> kable(format="markdown") | author | authorLabel | influencedBy | influencedByLabel | reference | referenceLabel |
|---|---|---|---|---|---|
| Q55185591 | Gonzalo G. Barreñada | Q170509 | Henry James | NA | NA |
| Q46248 | Terry Pratchett | Q312632 | Jack Vance | NA | NA |
| Q250754 | Álvares de Azevedo | Q49767 | François-Auguste-René de Chateaubriand | NA | NA |
| Q713270 | Ulf Lundell | Q392 | Bob Dylan | NA | NA |
| Q156268 | Pierre Bourdieu | Q9047 | Gottfried Wilhelm Leibniz | NA | NA |
| Q55771 | A. H. Salunkhe | Q468361 | Tukaram | NA | NA |
| Q533505 | Wendell Berry | Q444995 | Sarah Orne Jewett | NA | NA |
| Q7150861 | Paul Georgescu | Q1368307 | Mateiu Caragiale | NA | NA |
| Q4119221 | Jamal Naji | Q991 | Fyodor Dostoyevsky | NA | NA |
| Q5685 | Anton Chekhov | Q43718 | Nikolai Gogol | NA | NA |
Citation status of influence claims
Not many claims (3.5%) have references alongside them: it seems that many influence links were imported when Freebase data was uploaded, so there is no real record of how they were added. But for some of the influences, we can trace them to the sources via the author’s Wikipedia page, so adding references is not so difficult (The Micheal Chabon record, for instance, cites several of these in his Wikipedia entry, taken from this 2010 Guardian interview as the original source)
influence_data|> group_by(status=ifelse(is.na(reference), "no reference given", "reference provided")) |>
summarise(count = n()) |> kable(format="markdown")| status | count |
|---|---|
| no reference given | 2753 |
| reference provided | 101 |
Data Extraction and Graph Creation
The “influenced by” property is used for several kinds of creators and in various ways. In this case we are interested in writers being influenced by other writers. To extract provenance information (attached references), we need to include a handle to the property statement itself, using the p statement and ps statement property namespaces. Once we have that we can use the provenance “wasDerivedFrom” property to get information on any reference used.
SELECT
?author ?authorLabel
?influencedBy ?influencedByLabel
?reference ?referenceLabel
WHERE
{
?author p:P737 ?statement .
?statement ps:P737 ?influencedBy.
# writers
?author wdt:P106 wd:Q36180 .
?influencedBy wdt:P106 wd:Q36180 .
# people
?author wdt:P31 wd:Q5 .
?influencedBy wdt:P31 wd:Q5 .
# reference
OPTIONAL {
?statement prov:wasDerivedFrom ?refnode .
?refnode pr:P248 ?reference.
}
SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". } .
# not philosophers, theres too many of those
FILTER (
NOT EXISTS {?author wdt:P106 wd:Q4964182}
)
}
# remove or change limit for more results
ORDER BY ?author ?influencedBy
LIMIT 1000The wikidataR library lets us run the SPARQL against the wikidata endpoint and return a dataframe.
# This runs the sparql query in batches of 1000
# sparql_string <- "SELECT ... LIMIT 1000 OFFSET"
offset <- 0
influence_data <- tibble()
repeat {
fetch_data <- query_wikidata(paste(sparql_string, offset))
offset <- offset + 1000
influence_data <- influence_data |> bind_rows(fetch_data)
if (nrow(fetch_data) < 1000) {
break
}
}Creating the Graph
We can turn the dataset into a directed graph, reversing the columns which seems more logical (x influenced y, rather than y influenced by x).
auth_graph <- influence_data |> select(influencedByLabel, authorLabel) |> graph_from_data_frame(directed=TRUE)
print(paste("Directed graph with", length(auth_graph),"nodes,",length(as_edgelist(auth_graph)),"edges"))[1] "Directed graph with 2245 nodes, 5708 edges"
Create the interactive network map
We can visualise the influence network after simplifying it by removing orphaned components and filtering by nodes with at least 5 connections.
# Simplify the graph to only show the more influential nodes
graph_filtered <- largest_component(auth_graph)
important_v <- V(graph_filtered)[degree(graph_filtered) < 5]
graph_filtered <- delete_vertices(graph_filtered, important_v)
graph_filtered <- largest_component(graph_filtered)# Create influencer / influenced groups for colouring
wikifluencers <- V(graph_filtered)[degree(graph_filtered, mode = "out") > degree(graph_filtered, mode = "in")]
V(graph_filtered)$group = ifelse(V(graph_filtered) %in% wikifluencers, "influencer", "influenced")# This is to adjust node size according to out degree
V(graph_filtered)$value <- ifelse(degree(graph_filtered, mode = "out") == 0,1,degree(graph_filtered, mode = "out"))View the Graph
This uses the visNetwork package to turn the iGraph into an interactive visualisation using vis.js:
# Visualise
visIgraph(graph_filtered,
idToLabel = TRUE,
layout = "layout.graphopt",
physics = FALSE,
smooth = FALSE,
type = "full",
randomSeed = NULL,
layoutMatrix = NULL
) |>
visGroups(groupname = "influencer", color = "purple") |>
visGroups(groupname = "influenced", color = "orange") |>
visOptions(width="100%",highlightNearest = list(enabled = TRUE, degree = 1, hover = TRUE, labelOnly = FALSE)) |>
visInteraction(navigationButtons = TRUE, zoomView = TRUE) |>
visPhysics(stabilization = TRUE)Footnotes
Of course, many don’t accept that there can be so specific a thing. But I feel that there must be some validity and usefulness in influence claims when they come from the authors themselves or from expert critics↩︎
Bloom, H. (2012) The Anatomy of Influence: Literature as a Way of Life Reprint edition. Yale University Press.↩︎
Burt, D.S. (2009) The literary 100 : a ranking of the most influential novelists, playwrights, and poets of all time.New York, NY : Facts on File. Available from: http://archive.org/details/literary100ranki0000burt_v6e1.↩︎
The author admits that his list is subjective and based on a career in literature, and some input from other experts↩︎