Auswahl von erstem Wert über Schwellenwert

Allgemeine Statistik mit R, die Test-Methode ist noch nicht bekannt, ich habe noch keinen Plan!

Moderatoren: EDi, jogo

jogo
Beiträge: 2086
Registriert: Fr Okt 07, 2016 8:25 am

Re: Auswahl von erstem Wert über Schwellenwert

Beitrag von jogo »

Hallo R2,

kannst Du trotzdem bitte erstmal meine drei Fragen beantworten?

... ich mache mal trotzdem weiter.
Ja, Deine Idee ist prinzipiell richtig. Die Umsetzung in base R ist etwas holperig.
Als glatteste Lösung fällt mir die Nutzung von data.table ein.
Auch auf die Gefahr hin, dass Dich dies erstmal überfordert:

Code: Alles auswählen

library("data.table")

owid <- fread("https://covid.ourworldindata.org/data/owid-covid-data.csv")
owid[iso_code=="AFG", 1:4] ### ok, Datum scheint fortlaufend zu sein

owid[total_cases_per_million>12, .SD[1], iso_code] ### erster Tag nach Überschreitung

owid[total_cases_per_million>12, .SD[1:5], iso_code] ### die ersten fünf Tage nach Überschreitung
Gruß, Jörg
Rnest2
Beiträge: 11
Registriert: Mi Jan 27, 2021 2:33 pm

Re: Auswahl von erstem Wert über Schwellenwert

Beitrag von Rnest2 »

Hallo Jörg,

deine Fragen hatte ich bereits mit einem dreimaligen Ja beantwortet.
Dein Code funzt wunderbar und ist schnell an einen neuen Schwellenwert bzw. Zeitpunkt nach Überschreitung angepasst.
Klasse, vielen Dank!!!

Jetzt gibt es natürlich noch einige Sachen, die ich gerne verstehen möchte.
1) Bevorzugst du generell "fread" vor "read.csv" - ich habe vorhin deinen Code ausprobiert und das mit "read.csv" eingelesene dataframe "owid" hat R nicht gefunden. Fehlermeldung: "Fehler in `[.data.frame`(owid, total_cases_per_million > 10, .SD[1], : Objekt 'iso_code' nicht gefunden". Mit "fread" läufts.
2) In der Funktion hätte ich jetzt angenommen, dass ".SD" sich auf das Datum bezieht, aber nach kurzem(!) Überfliegen der Dokumentation zum Package ‘data.table’, würde ich es laienhaft so ausdrücken, dass die Funktion den [1]. Wert nach Überschreitung "ausspuckt. Dies in diesem Fall zu dem was ich erreichen will, weil die Daten chronologisch geordnet sind. Richtig?

3)OFFTOPIC EIne generelle Frage zum Datenmanagement in R. Ich verwende neben dem OWID-Datensatz noch folgende
https://github.com/OxCGRT/covid-policy- ... latest.csv
Von beiden Datensätzen habe ich noch Versionen aus dem September 2020, welche deutlich kleiner (weniger Variablen und Ausprägungen) sind. Beim mergen eines subsets beider Datensätze per

Code: Alles auswählen

datamerge <- merge(x=oxford_cut, y=owid_cut, all.x = TRUE, by.x = "iso_code",
               by.y = "iso_code")

hat R ganz schön gerödelt. Weitere Bearbeitungsschritte haben nur noch verzögert erledigt werden können.. Hab das Programm dann per Task-Manager erlöst. Der MErge hat auch nicht korrekt funktioniert, aber das ist erstmal Nebensache. Eine später testweise exportierte CSV-Datei war über 2GB groß - der Export hat locker 10 minuten gedauert..
Für irgendwas hierzu würde ich mich über einen Kommentar oder links freuen, da ich neben den beiden Datensätze einn weiteren mit den UVs aller untersuchten Staaten erstellen und auch verknüpfen muss..

Gruß R2
jogo
Beiträge: 2086
Registriert: Fr Okt 07, 2016 8:25 am

Re: Auswahl von erstem Wert über Schwellenwert

Beitrag von jogo »

Hallo R2
Rnest2 hat geschrieben: Sa Jan 30, 2021 3:08 pm deine Fragen hatte ich bereits mit einem dreimaligen Ja beantwortet.
hatte ich vorher irgendwie überlesen - war wahrscheinlich zu knapp formuliert (dabei bin ich durchaus ein Freund von solchen knackigen Formulierungen). Bitte entschuldige, dass ich das 3* "ja" nich bemerkt habe.
Dein Code funzt wunderbar und ist schnell an einen neuen Schwellenwert bzw. Zeitpunkt nach Überschreitung angepasst.
Klasse, vielen Dank!!!
sehr schön.
Jetzt gibt es natürlich noch einige Sachen, die ich gerne verstehen möchte.
1) Bevorzugst du generell "fread" vor "read.csv" - ich habe vorhin deinen Code ausprobiert und das mit "read.csv" eingelesene dataframe "owid" hat R nicht gefunden. Fehlermeldung: "Fehler in `[.data.frame`(owid, total_cases_per_million > 10, .SD[1], : Objekt 'iso_code' nicht gefunden". Mit "fread" läufts.
sagen wir es mal so: ohne das Paket "data.table" läuft nichts, denn die Funktion fread() ist ein Teil von data.table. Die Funktion kann nur gefunden werden, wenn das Paket geladen ist.
2) In der Funktion hätte ich jetzt angenommen, dass ".SD" sich auf das Datum bezieht, aber nach kurzem(!) Überfliegen der Dokumentation zum Package ‘data.table’, würde ich es laienhaft so ausdrücken, dass die Funktion den [1]. Wert nach Überschreitung "ausspuckt. Dies in diesem Fall zu dem was ich erreichen will, weil die Daten chronologisch geordnet sind. Richtig?
bezüglich .SD ist das dritte Argument in [] wichtig:
Das dritte Argument gibt die Gruppierung vor. Nun ist .SD der Platzhalter für einen Teil (entsprechend der Gruppierung) des ursprünglichen Datatable.
.SD[1] in data.table-Syntax bedeutet einfach die erste Zeile von .SD
Alles zusammen:
* gruppiere nach iso_code
* nimm aus jedem Teil-Datatable die erste Zeile

... ach so - fast hätte ich es vergessen:
zuerst wirkt die Bedingung aus dem ersten Argument: also nimm nur die Zeilen, bei denen die Bedingung
total_cases_per_million>12 erfüllt ist.
Kennst Du SQL? -- es gibt gewisse Parallelen zu den drei Argumenten von [] bei data.table

Vielleicht das Verwirrendste für jemanden, der data.table erstmalig in Aktion sieht:
das Paket bringt eigene Datentypen mit (die Objekte vom Typ data.table) und definiert für diesen Datentyp die Funktion
`[`() neu, so dass [] anders funktioniert als bei einem Dataframe.
3)OFFTOPIC EIne generelle Frage zum Datenmanagement in R. Ich verwende neben dem OWID-Datensatz noch folgende
https://github.com/OxCGRT/covid-policy- ... latest.csv
Von beiden Datensätzen habe ich noch Versionen aus dem September 2020, welche deutlich kleiner (weniger Variablen und Ausprägungen) sind. Beim mergen eines subsets beider Datensätze per

Code: Alles auswählen

datamerge <- merge(x=oxford_cut, y=owid_cut, all.x = TRUE, by.x = "iso_code",
               by.y = "iso_code")

hat R ganz schön gerödelt. Weitere Bearbeitungsschritte haben nur noch verzögert erledigt werden können.. Hab das Programm dann per Task-Manager erlöst. Der MErge hat auch nicht korrekt funktioniert, aber das ist erstmal Nebensache. Eine später testweise exportierte CSV-Datei war über 2GB groß - der Export hat locker 10 minuten gedauert..
Für irgendwas hierzu würde ich mich über einen Kommentar oder links freuen, da ich neben den beiden Datensätze einn weiteren mit den UVs aller untersuchten Staaten erstellen und auch verknüpfen muss..
wichtig wäre erstmal, zu wissen, welcher Art das merge() ist:
m * n oder
1 * n oder
m * 1

Annahme Du hast zwei Tabellen zu merken (für Datenbankleute: join)
Tabelle1: m1 Zeilen, n1 Spalten
Tabelle2: m2 Zeilen, n2 Spalten
Im schlimmsten Fall bekommt man beim join eine Tabelle mit
m1*m2 Zeilen und
(n1+n2-1) Spalten

Da bei Dir die eine Tabelle fast 70000 Zeilen hat, ist es angebracht, das Vorgehen gut zu überlegen. Gelegentlich kann man sich bei solchen Operationen recht dumm anstellen ... oder auch nicht.

Gruß, Jörg
Rnest2
Beiträge: 11
Registriert: Mi Jan 27, 2021 2:33 pm

Re: Auswahl von erstem Wert über Schwellenwert

Beitrag von Rnest2 »

Hallo Jörg,

vielen Dank für deine Erläuterungen. Ich bin mal gespannt, wie tief ich mich, abgesehen von der ganzen statistischen Analyse und den jeweiligen Darstellungen davon, noch in den Kaninchenbau von R reinziehen lassen muss..
jogo hat geschrieben: Sa Jan 30, 2021 4:49 pm Im schlimmsten Fall bekommt man beim join eine Tabelle mit
m1*m2 Zeilen und
(n1+n2-1) Spalten

Da bei Dir die eine Tabelle fast 70000 Zeilen hat, ist es angebracht, das Vorgehen gut zu überlegen. Gelegentlich kann man sich bei solchen Operationen recht dumm anstellen ... oder auch nicht.
Tja ja, da hast du den Nagel auf den Kopf getroffen.. Da hab ich wenigstens einmal großes Kino produziert.. Aus zwei Datenbanken mit jeweils ca. 40k Ausprägungen habe ich lockere 13 Mio. berechnen lassen.. :lol:
Trial Error Success, oder wie man so schön sagt..

Danke nochmal für die Hilfe! Ich hoffe dass ich weitere Veränderungen am Code selbstständig hinbekomme..

R2
Athomas
Beiträge: 769
Registriert: Mo Feb 26, 2018 8:19 pm

Re: Auswahl von erstem Wert über Schwellenwert

Beitrag von Athomas »

Ich möchte an dieser Stelle eine kleine Übersicht über die ("Join"-) Möglichkeiten von data.table geben und sie in die den meisten wohl bekannte SQL-Bezeichnungswelt einordnen.

Dabei habe ich den Artikel "JOINing data in R using data.table" https://rstudio-pubs-static.s3.amazonaw ... 0e775.html verwendet und die Beispiele etwas "aufgepumpt", um die Performance von data.table zu verdeutlichen.

Code: Alles auswählen

library(data.table)

#-------------- Erzeugung und Speicherung von "Spielmaterial" ------------------

Zeilen  <- 1000000
Spalten <- 20

DT <- data.table(matrix(runif(Zeilen*Spalten), ncol=Spalten))
DT[  , ID:=1:.N]

system.time(fwrite(DT, "R:/temp/testdaten.csv"))

system.time(DT.neu <- fread("R:/temp/testdaten.csv"))

#       A enthält 90% der Zeilen mit den Spalten ID und V1 bis V10

AVars <- c("ID", paste0("V", 1:10))
ran.A <- sample(c(TRUE,FALSE), Zeilen, prob=c(0.9, 0.1), replace=TRUE)
A <- DT.neu[ran.A][  , AVars, with=FALSE]
setkey(A, ID)

#       B enthält 90% der Zeilen mit den Spalten ID und V11 bis V20

BVars <- c("ID", paste0("V", 11:20))
ran.B <- sample(c(TRUE,FALSE), Zeilen, prob=c(0.9, 0.1), replace=TRUE)
B <- DT.neu[ran.B][  , BVars, with=FALSE]
setkey(B, ID)

#---------------  Diverse Joins zwischen A und B -------------------------------

system.time(innerJoin.1 <- A[B, nomatch=0])
system.time(innerJoin.2 <- merge(A, B, all=FALSE))           # das ist das data.table-merge - nicht das "ordinäre" base-merge!

system.time(leftOuter.1 <- B[A])
system.time(leftOuter.2 <- merge(A, B, all.x=TRUE))

system.time(rightOuter.1 <- A[B])
system.time(rightOuter.2 <- merge(A, B, all.y=TRUE))

system.time(fullOuter <- merge(A, B, all=TRUE))

Wer mehr über data.table wissen möchte, findet im Netz reichlich Literatur!

Einem data.table-Anfänger (mit elementaren R-Vorkenntnissen) würde ich das "data.table Tutorial (with 50 Examples)" empfehlen: https://www.listendata.com/2016/10/r-data-table.html
Athomas
Beiträge: 769
Registriert: Mo Feb 26, 2018 8:19 pm

Re: Auswahl von erstem Wert über Schwellenwert

Beitrag von Athomas »

Auf Grund des Hinweises, dass
  • DT (und damit A und B) bereits nach ID sortiert sind - was möglicherweise die Verarbeitung beschleunigen könnte - und
  • die für die Erstellung der Keys benötigte Zeit ebenfalls ausgewiesen werden sollte
hier noch eine (leicht) veränderte Fassung:

Code: Alles auswählen

library(data.table)

#-------------- Erzeugung und Speicherung von "Spielmaterial" ------------------

Zeilen  <- 1000000
Spalten <- 20

DT <- data.table(matrix(runif(Zeilen*Spalten), ncol=Spalten))
DT[  , ID:=1:.N]

setorder(DT, "V17")                                                             # für Ungläubige

system.time(fwrite(DT, "R:/temp/testdaten.csv"))

system.time(DT.neu <- fread("R:/temp/testdaten.csv"))

#       A enthält 90% der Zeilen mit den Spalten ID und V1 bis V10

AVars <- c("ID", paste0("V", 1:10))
ran.A <- sample(c(TRUE,FALSE), Zeilen, prob=c(0.9, 0.1), replace=TRUE)
A <- DT.neu[ran.A][  , AVars, with=FALSE]
system.time(setkey(A, ID))

#       B enthält 90% der Zeilen mit den Spalten ID und V11 bis V20

BVars <- c("ID", paste0("V", 11:20))
ran.B <- sample(c(TRUE,FALSE), Zeilen, prob=c(0.9, 0.1), replace=TRUE)
B <- DT.neu[ran.B][  , BVars, with=FALSE]
system.time(setkey(B, ID))

#---------------  Diverse Joins zwischen A und B -------------------------------

system.time(innerJoin.1 <- A[B, nomatch=0])
system.time(innerJoin.2 <- merge(A, B, all=FALSE))

system.time(leftOuter.1 <- B[A])
system.time(leftOuter.2 <- merge(A, B, all.x=TRUE))

system.time(rightOuter.1 <- A[B])
system.time(rightOuter.2 <- merge(A, B, all.y=TRUE))

system.time(fullOuter <- merge(A, B, all=TRUE))
Antworten