Hur programmera mot Swepubs csv-filer?

Swepub har lanserat en bibliometrisida som låter användare specificera en sökning och sedan ladda ned resultaten i ett flertal öppna format (csv, tsv, xml, json). Detta är väldigt positiva nyheter för oss forskare som vill göra scientometriska analyser, och äntligen ett bibliometriskt index som inte är kontrollerat av stora företag!

Men jag funderar nu på hur jag på ett smart sätt ska kunna programmera mot den data man får ut ur Swepubsystemet. Det är nämligen så att varje artikel förekommer flera gånger. Om man till exempel sparar ned en csv-fil ser det ut så här om man öppnar den i exempelvis LibreOffice (eller Excel):

Screenshot from 2016-01-16 14:34:32

Varje artikel har ett unikt Swepubnummer, vilket gör det enkelt att isolera artikelnivån. Men sedan är varje författare angiven i en ny rad, istället för att vara inkluderade men separerade inom ett och samma värden, vilket är fallet med data från Web of Science och Scopus. Detta är lite ”jobbigt”. Men givetvis går det att ordna. Jag letar nu efter den enklaste och mest eleganta lösningen och behöver lite input.

En av de mest intressanta analyserna är samförfattarskap. Att se vilka som skriver artiklar tillsammans kan vara ett väldigt kraftfullt mått på interdisciplinaritet, internationalisering, forskningspraktiker osv. Men då måste man för varje artikel få en lista på författare (och gärna så mycket meta-data om dessa författare som möjligt, ex. institutionstillhörighet).

Csv-filen är superenkel att läsa in till Python:

import csv

thefile = open('query_result.csv', 'r')
csv = csv.reader(thefile, delimiter=',')
next(csv) #remove headers

for c in csv:
    print(c[24]) #put here what values you want, see list below.

Därefter är det bara att välja vilken meta-data man önskar. Jag begriper inte allt, men här är ett första index (om ni vet mer kommentera gärna):

 """
[0] = Swepub ID-nummer
[1] = Organisation/Lärosäte (ex. "gu")
[2] = Publikationsår
[3] = Status (ex. "PUBLISHED")
[4] = Publikationstyp
[5] = Innehållstyp
[6] = Publikationstyp (igen)
[7] = Open Access-status (ex. "gold", "green")
[8] = "_hsv1" ?
[9] = "_hsv3" ?
[10] = "_hsv5"?
[11] = Titel
[12] = Antal författare
[13] = "_numLocalCreator", ?
[14] = Författar (namn)
[15] = Användarnamn i systemet (ex. xjsode)
[16] = ORCID (se http://orcid.org)
[17] = Affiliering (ex. "gu.se")
[18] = Källa (ex. "Journal of Python Snakes")
[19] = ISSN
[20] = Förlag
[21] = URL
[22] = Fulltext (länk till URL)
[23] = ISI-nummer (Web of Science)
[24] = DOI
[25] = Scopus-nummer
[26] = Pubmed-nummer
[27] = ISBN
[28] = "_projekt", ?
[29] = "_program", ?
[30] = "_contract", ?
[31] = "_dubblettID" ?
"""

Eftersom Swepub ID är unikt, är det ju enkelt att isolera artiklar var för sig. Men jag skulle vilja skriva en funktion som gjorde ungefär så här:

För varje unikt Swepub-ID, gå igenom alla författare och bygg om [14] till en lista (eller kanske en lista av dictionaries/hashtabeller) som inkluderar författarnamn + ORCID + Affiliering.

På så sätt kan man sedan enkelt ta varje artikel och genast skapa ett co-authornätverk. Här finns massor av intressanta analyser att göra. Hur mycket tvärvetenskap finns på svenska universitet? Hur internationella är forskare egentligen? Vilka institutioner samarbetar ofta?

Men allt hänger på att man hittar en smidig lösning på att varje artikel förekommer flera gånger och att metadata kan sammafogas på ett smart sätt.

Någon som har en intressant och elegant strategi för att bygga om datamängden så här? Kanske är det enklare med json?

Länk till datamängden jag jobbar mot (1.7 Mb, zip)

Uppdatering: Mattias Östmar har löst problemet så här. (se även kommentarerna nedan).

7 reaktioner till “Hur programmera mot Swepubs csv-filer?”

  1. Hej igen!
    Jag hoppas att jag förstod ditt problem rätt, jag blev lite förvirrad av att det var så många författare per recordID. Här är i alla fall ett sätt att få ut unika författare per recordID. Genom att mecka med koden kan du ändra den som du vill ha den i slutändan förhoppningsvis. Hojta till i valfri kanal om du har några frågor eller om jag missförstod vad du ville få ut.

    https://github.com/mattiasostmar/swepub_datawrangling_example/blob/master/swepub_csv_fil.ipynb

  2. Funkar väldigt bra! Ska jobba in lite modifikationer och sedan testa att bygga lite analyser på det.

    Upptäcker nu att Swepub inte har med institutionstillhörighet utan endast lärosäte när man hämtar datamängden på detta sätt. För att få institution måste man gå via APIt.

  3. Generell metod för att lösa problem av den här typen:

    Mappifiera all datan. Det vill säga, populera hashmaps med datan från varje rad.
    map[artikelnamn]->[lista av författare]
    map[författarnamn]->[lista på artiklar]
    map[lärosäte]->[lista på författare]
    map[lärosäte]->[lista på artiklar]
    etc

    func add2InnerSet(map, key, value) {
    if(!map.contains(key))
    map.add(key, new list)
    map[key].addToListSomehow(value)
    }

    mapAuthor2Papers = ny hashmap med key=string, value = lista av strängar
    mapPapers2Authors = ny hashmap med key=string, value = lista av strängar
    etc

    For rad in allaRader {
    add2InnerSet(mapAuthor2Papers, rad.authorName, rad.paperName)
    add2InnerSet(mapPapers2Authors, rad.paperName, rad.authorName)
    add2InnerSet(mapInstitution2Authors, rad.institutNamn, rad.authorname)
    etc
    }

    sedan har du kartlagt allt i extremt snabba hashmaps, som du sedan kan slå i genom ytterligare kod.

    for paper in mapAuthor2Paper[”Christopher kullenberg”] {
    for author mapPaper2Author[paper] {
    if author != ”christopher kullenberg” print author
    }
    }

    skriver då ut alla författare som du någonsin medförfattat en artikel med.

    och så vidare. bara vilka maps du skapar sätter gränserna.

    1. Herp: Tack för detta! Intressant approach som ju är flexibel för olika typer av analyser. Jag ska läsa på lite och experimentera hur man kan skriva fram dessa funktioner. När man väl har populerat en hash/dictionary är de ju supersnabba. Däremot tar det lite tid (fem sekunder typ) att förhindra att duplikata värden läggs till. Men det är oproblematiskt i sammanhanget.

      (hela Swepub, dvs. all data, är bara ~6 Gb, vilket gör riktigt stora analyser möjliga)

    1. Great! Tack Peter! Jag tänker att nätverksanalysen är speciellt intressant på institutionsnivå. Jag lade en ticket hos swepub för att höra om det är möjligt att få institiutionstillhörighet (och inte bara lärosäte) i csv-filerna.

Kommentera

E-postadressen publiceras inte. Obligatoriska fält är märkta *

Time limit is exhausted. Please reload CAPTCHA.