Strings in Dataframe nach Unterthemen durchsuchen

Wie rufe ich R-Funktionen auf, wie selektiere ich Daten, ich weiß nicht genau ....

Moderatoren: EDi, jogo

bigben
Beiträge: 2778
Registriert: Mi Okt 12, 2016 9:09 am

Re: Strings in Dataframe nach Unterthemen durchsuchen

Beitrag von bigben »

Dörk hat geschrieben: Di Sep 01, 2020 7:39 pm diese Daten auszulesen mit Tidytext nach ngrams oder nur einfachen Wörtern zu suchen nach Häufigkeit aufzusplitten
Hmmmmm-die Aufgabenstellung ist tidy und Athomas hat schonmal was vorbereitet? Jetzt bin ich gespannt, ob die Antwort tidy wird oder aus eckigen Klammern, Sonderzeichen und Großbuchstaben besteht :P :P :?:
@Athomas: Ich kann dir auf die PN nicht antworten.
IIRC hatte Athomas das Problem auch schon mal und hat es dann gelöst, indem er in einem Thread im off topic einfach eine Reihe von Nonsens-Posts hintereinander gestellt hat. Hat damals recht schnell funktioniert und es hat sich auch ein netter Moderator gefunden, der das nachher aufgeräumt hat.
Ich hoffe ich konnte etwas licht ins dunkle bringen.
Also ich hab zum Beispiel noch nicht kapiert, ob und wie die Daten aus dem Text mit den Daten aus den strukturierten CSV verknüpft werden sollen. Braucht jede Anamnese und jede Entlassdiagnose einen Bezug zur Patienten-ID, damit man das mergen kann oder ist die Freitextanalyse eigenständig und ohne Verknüpfung zu den Laborwerten? Wäre ja für die Textanalyse wichtig zu wissen, ob man eine Patienten-ID auslesen muss, oder nicht.

LG,
Bernhard
---
Programmiere stets so, dass die Maxime Deines Programmierstils Grundlage allgemeiner Gesetzgebung sein könnte
Dörk
Beiträge: 10
Registriert: Sa Aug 29, 2020 7:06 pm

Re: Strings in Dataframe nach Unterthemen durchsuchen

Beitrag von Dörk »

Also meine Idee war folgendermaßen: Ich strukturiere die Daten nach Topic hier wäre eine Zuordnung zur Patientid und AdmissionID auch sinnvoll, damit ich später nicht wieder durch den gesamten Freitext suchen muss. Dann Erstelle zu jedem Topic eine Art dictionary. Schaue mir das Dict auf medizinische Relevanz durch (nach Häufigkeit eine Vorselektion und dann per Hand). Jedes Symptom oder Befund (Also vorallem Schlagworte z.B. "pleural effusion" oder "effusion Thorax") erhält ein Datenfeld (TRUE/FALSE) in einer Tabelle mit einem Bezug auf die PatientenID und AdmissionID. Wenn Symptom/Befund in Topic vorhanden, dann TRUE, wenn verneint oder nicht vorhanden, dann FALSE. Ich weiss zwar nicht, ob mein Vorgehen so sinnvoll oder gut programmiert wäre (Habe mit so großen Datenmengen noch kaum Erfahrung) aber mir ist nix besseres eingefallen um das Problem zu lösen.

Also lange Erklärung kurz: für die Erstellung des DICT ist der Bezug AdmissionID und PatientID nicht notwendig, für die anschließende Analyse schon.

TidyText war das erste Package das ich gefunden habe zum ermitteln von Beziehungen von Wörtern und es erschien mir praktikabel. Wenn es anders geht, finde ich das auch super! Ich bin da ja noch ziemlich unbefleckt was R-Techniken oder Vorlieben betrifft. Ich möchte vor allem die Daten vorbereiten und verarbeitbar machen für bnlearn.

Gruß
Dörk
Athomas
Beiträge: 769
Registriert: Mo Feb 26, 2018 8:19 pm

Re: Strings in Dataframe nach Unterthemen durchsuchen

Beitrag von Athomas »

Du hattest ja vorgehabt, eine Liste von Topics, nach denen der Text durchsucht werden sollte, vorzugeben und den Inhalt eines Topics bis zum Beginn des nächsten auszulesen.

Dieses Vorgehen hat zwei wesentliche Nachteile: zum einen gibt es sehr menschliche Varianten der Schreibweisen, die bei einer "einfachen" Textsuche dazu führen würde, dass viele Stellen nicht entdeckt werden.
Zum anderen würden von Dir nicht vorgegebene Topics zusammen mit dem Text des letzten gefundenen Topic extrahiert und so dessen Inhalt "belasten"!

Ich habe daher einen Vorlauf eingefügt, in dem erstmal alle Textstellen mit "Topicverdacht" in eine Excel-Datei geschrieben werden. In dieser Datei kannst Du dann neben jeden Eintrag Deine "Übersetzung" (so eine Art Norm-Topic) schreiben. Kein Eintrag bedeutet: kein Topic, sieht nur so aus! Im eigentlichen Suchlauf bilden dann die ursprünglichen Topics das Suchziel, die dann aber mit Deinen "Normtopics" bezeichnet werden. Es ist aber wichtig, dass auch die uninteressanten Topics identifiziert werden, damit sie nicht als Text an andere Topics angehängt werden. Sie werden dann extrahiert, ignorieren kannst Du sie später immer noch :) !

Dieses Vorgehen basiert darauf, dass die Datei, die Du zur Verfügung gestellt hast, eine "ordinäre" csv-Datei ist - halt mit einem ziemlich langen Textfeld.
In dem Textfeld steckt steckt der Entlassungsbericht des jeweiligen Patienten - mit allen Formatierungen. Und - das ist zumindest mein Eindruck - eigentlich sollen Topics die Form haben - um es mal mit R-RegEx zu sagen "\\r\\n\\r\\n[ a-zA-Z]+:" - was heißt neue Zeile, Leerzeile, Text aus Buchstaben und Leerzeichen und danach einen Doppelpunkt!

Code: Alles auswählen

library(data.table)
library(openxlsx)
library(stringr)

Basisordner     <- "P:/R/R Forum/Diagnose Auswertungen"

texte           <- fread(file.path(Basisordner, "DischSumm_example.csv"))

#--- Vorbereitung, Erstellung der Vorlage für Übersetzungstabelle --------

Sammlung        <- list()

for (i in 1:nrow(texte)){
  Patient       <- texte[i, TEXT]
  Fundstellen   <- data.table(str_locate_all(Patient, pattern="\\r\\n\\r\\n[ a-zA-Z]+:")[[1]])
  Fundstellen[  , topic:=str_trim(str_sub(Patient, start + 2, end))]
  Fundstellen[  , Patient:=i]
  Sammlung[[i]] <- Fundstellen
}

Alles           <- rbindlist(Sammlung)
Extrakt         <- Alles[  , .N, by=topic]
Extrakt[  , TOPIC:=str_trim(toupper(topic))]

#        Rohtopics mit zugehöriger Großschreibung
write.xlsx(Extrakt, file.path(Basisordner, "Rohtopics.xlsx")) 


#        Topics mit Häufigkeiten bzgl. der Großschreibungs-Variante
zuErgänzen <- Extrakt[  , .(wie.oft=sum(N)), by=TOPIC]                   
write.xlsx(zuErgänzen, file.path(Basisordner, "TOPICS.xlsx"))             
#        in dieser Excel-Datei müssen die Übersetzungen (Spaltenname "Übersetzungen" vergeben) hinzugefügt werden!
#        Das Ganze wieder unter "TOPICS plus Übersetzungen.xlsx" speichern.
#        Bitte auch uninteressante Topics übersetzen: nur echte Falschmeldungen
#        erhalten keine Übersetzung!

#-------- Wenn Übersetzungstabelle fertig: -------------------------------
#         Falls R zwischendurch beendet:
#         Datei "texte" (s.o.) und beteiligte libraries nochmal laden

Extrakt         <- data.table(read.xlsx(file.path(Basisordner, "Rohtopics.xlsx")))
setkey(Extrakt, TOPIC)
Transl          <- data.table(read.xlsx(file.path(Basisordner, "TOPICS plus Übersetzungen.xlsx")))
setkey(Transl, TOPIC)

Zsamma          <- Transl[Extrakt]

verwenden       <- Zsamma[!is.na(Übersetzung), .(topic, Übersetzung)]
setkey(verwenden, topic)

#================================================

#        Hier wird der reine Text (ohne die Zeilenumbrüche) verwendet!

Muster          <- paste(verwenden[  , topic], collapse="|")
Sammlung.2      <- list()

for (i in 1:nrow(texte)){
  Patient       <- texte[i, TEXT]
  Fundstellen   <- data.table(str_locate_all(Patient, pattern=Muster)[[1]])
  Fundstellen[  , topic:=str_trim(str_sub(Patient, start, end))]
  Fundstellen[  , PNr:=i]
  setkey(Fundstellen, topic)
  FundPlus      <- verwenden[Fundstellen]
  setorder(FundPlus, start)
  Patend        <- nchar(Patient)
  FundPlus[  , ":="(text_start=end + 1, text_end=c(tail(start, -1) - 1, Patend))]
  FundPlus[  , Beschreibung:=str_trim(str_sub(Patient, text_start, text_end))]
  Sammlung.2[[i]] <- FundPlus
}

Patientendaten  <- rbindlist(Sammlung.2)
bigben
Beiträge: 2778
Registriert: Mi Okt 12, 2016 9:09 am

Re: Strings in Dataframe nach Unterthemen durchsuchen

Beitrag von bigben »

Hallo Athomas,

nach meinem Post, dass ich von Dir eher eine data.table Lösung erwarte (und da hast Du ja nicht enttäuscht) sieht das jetzt vielleicht so aus, also ob ich eine tidyverse-Obsession hätte, was tatsächlich nicht der Fall ist. In diesem Sinne aus echtem Interesse und ohne Geifer: Warum machst Du den Code abhängig von stringr? Ich sehe die Funktionen str_sub und str_trim. Ist str_sub besser als substr? Ist str_trim besser als trimws? Oder war es nur bequemer, beide Funktionen in derselben Packagedokumentation zu finden?

Neugierige Grüße,
Bernhard


edit: oha, ich habe ein str_locate_all übersehen, das oberflächlich betrachtet ein längerer Name für grep zu sein scheint.
---
Programmiere stets so, dass die Maxime Deines Programmierstils Grundlage allgemeiner Gesetzgebung sein könnte
Athomas
Beiträge: 769
Registriert: Mo Feb 26, 2018 8:19 pm

Re: Strings in Dataframe nach Unterthemen durchsuchen

Beitrag von Athomas »

In diesem Sinne aus echtem Interesse und ohne Geifer: Warum machst Du den Code abhängig von stringr?
Einfache Antwort: weil ich stringr-Fan bin :D !
Um einer Nachfrage vorzubeugen: ja, das geht! Tidyverse-Skeptiker und stringr- (sowie ggplot2-) Fan...
Man kann die Funktionen ja (gottseidank) auch ohne das Tidyverse-Tüdelütt nutzen!
Warum machst Du den Code abhängig von stringr?
Weil, wie gesagt, stringr gile ist und ich gute Erfahrungen im Zusammenspiel mit data.table gemacht habe. Ich wollte einfach meine Gewohnheiten nicht wegen der Beantwortung einer Forums-Frage über Bord werfen und Verwicklungen riskieren!
bigben
Beiträge: 2778
Registriert: Mi Okt 12, 2016 9:09 am

Re: Strings in Dataframe nach Unterthemen durchsuchen

Beitrag von bigben »

Cool! :)
---
Programmiere stets so, dass die Maxime Deines Programmierstils Grundlage allgemeiner Gesetzgebung sein könnte
Dörk
Beiträge: 10
Registriert: Sa Aug 29, 2020 7:06 pm

Re: Strings in Dataframe nach Unterthemen durchsuchen

Beitrag von Dörk »

Danke! Ich werde es nachher mal ausprobieren und mir das mal genauer anschauen.

Die Idee mit dem Excel-Sheet ist Klasse. Ich nehme an, ich kann auch mehreren Topics das gleiche Feld zu weisen.

by the way: ich hab noch mal ne Frage abseits meines Thread-Themas. Lässt sich die R beschleunigen? Mein PC sollte mit SSD, 16 Kernen und 90gb Ram eigentlich schneller sein als meine Portable Möhre, aber leider verwendet R nur 1-2 Kerne beim Code ausführen gibt es da einen Trick um die Leistung zu erhöhen?

Grüße
Dörk
Athomas
Beiträge: 769
Registriert: Mo Feb 26, 2018 8:19 pm

Re: Strings in Dataframe nach Unterthemen durchsuchen

Beitrag von Athomas »

Lässt sich die R beschleunigen? Mein PC sollte mit SSD, 16 Kernen und 90gb Ram eigentlich schneller sein als meine Portable Möhre, aber leider verwendet R nur 1-2 Kerne beim Code ausführen gibt es da einen Trick um die Leistung zu erhöhen?
Normalerweise rennst Du mit dieser Frage bei mir offene Türen ein, aber ich habe Deinen "Ernstfall" simuliert und die Beispielsdatei 1200 mal aneinandergehängt. Mein Rechner, der vor 4 Jahren top war, brauchte dafür ca. 6,5 Minuten...
Deshalb habe ich von einem Optimierungsversuch abgesehen!

Aber ich gebe Dir Recht, das Problem müsste sich in weiten Teilen gut parallelisieren lassen - durch Parallelbehandlung der Patienten :) !
Dörk
Beiträge: 10
Registriert: Sa Aug 29, 2020 7:06 pm

Re: Strings in Dataframe nach Unterthemen durchsuchen

Beitrag von Dörk »

Athomas hat geschrieben: Mi Sep 02, 2020 7:09 pm Normalerweise rennst Du mit dieser Frage bei mir offene Türen ein, aber ich habe Deinen "Ernstfall" simuliert und die Beispielsdatei 1200 mal aneinandergehängt. Mein Rechner, der vor 4 Jahren top war, brauchte dafür ca. 6,5 Minuten...
Deshalb habe ich von einem Optimierungsversuch abgesehen!

Aber ich gebe Dir Recht, das Problem müsste sich in weiten Teilen gut parallelisieren lassen - durch Parallelbehandlung der Patienten :) !
Nee, passt schon, bezog sich nicht auf deinen Code! Ist mir nur in den letzten Tagen aufgefallen, als ich ein paar andere Sachen aus den Daten gezogen habe. Eine csv Datei in dem Source ist so gigantisch, das alleine beim einlesen der Daten über read.csv das R über 40 minuten lang liest und liest und liest.... Hab gedacht es gibt einen Enviroment Hack, der das beschleunigen kann.

Kurze Frage noch du hast in den Kommentaren im Code geschrieben die Spalte in der xlsx soll "Übersetzungen" lauten. Wenn ich mir diese Codezeile anschaue....

Code: Alles auswählen

verwenden       <- Zsamma[!is.na(Übersetzung), .(topic, Übersetzung)]
... hätte ich erwartet, das ich die Spalte "Übersetzung" nennen muss. :?:

Oder mache ich da einen Denkfehler?

Grüße
Dirk
Athomas
Beiträge: 769
Registriert: Mo Feb 26, 2018 8:19 pm

Re: Strings in Dataframe nach Unterthemen durchsuchen

Beitrag von Athomas »

Eine csv Datei in dem Source ist so gigantisch, das alleine beim einlesen der Daten über read.csv das R über 40 minuten lang liest und liest und liest...
Man liest ja auch - wie ich es tue - mit "fread" aus data.table ein, das ist -zig mal schneller, vor allem von (NVMe-) SSD!
... hätte ich erwartet, das ich die Spalte "Übersetzung" nennen muss.
Du hast Recht!
Antworten