Funktion zum Datenimport

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

Moderatoren: EDi, jogo

Jörg
Beiträge: 16
Registriert: Mi Nov 09, 2016 2:58 pm

Funktion zum Datenimport

Beitrag von Jörg » Fr Sep 06, 2019 12:13 pm

Liebe alle,
Zum Hintergrund: Ich will viele csv Tabellen importieren, die sich im Aufbau (Variablen) sehr ähnlich sind, aber es gibt auch immer wieder kleinere Unterschiede. Diese sollen am Ende zu einem Datensatz zusammengefügt werden. Da diese Aufgabe eine wiederkehrende ist, wollte ich eine Funktion zum Importieren schreiben.

Unten findet Ihr eine stark vereinfachte Version der Funktion "import", mit der ich nur auf meine beiden aktuellen Probleme eingehen will. Außerdem anbei zwei Beispieldatensätze, die Ihr in Euerem Arbeitsverzeichnis speichern müsstet.
Beispieltabellen:
Bsp2.csv
(26 Bytes) 6-mal heruntergeladen
Bsp1.csv
(37 Bytes) 6-mal heruntergeladen
Zum einen klappt zwar grundsätzlich der Import und auch das erneute Speichern wie gewollt, ich möchte aber, dass die jeweilige Tabelle anschließend unter dem jeweiligen Namen im Workspace geladen ist. Siehe #2 im Code.
Außerdem gibt es Tabellen (hier Bsp2), die eine bestimmte Variable(hier Var3) nicht beinhalten. Innerhalb der Funktion sollte also eine entsprechende Abfrage und gegebenenfalls eine Erweiterung des Datensatzes geben (siehe #1 im Code).

Code: Alles auswählen

import<-function(Name_DF){
library(readr) 
df<-paste(Name_DF,".csv",sep="")
DF<- read_delim(df, ";", escape_double = FALSE, col_types = cols(Var1 = col_character(), Var2 = col_number(), Var3 = col_number()), trim_ws = TRUE)

# 1. Es fehlt eine Abfrage, die überprüft, ob der zu importierende Datensatz eine bestimmte Variable mit Namen Namen "Var3" beinhaltet.
#Wenn ja (wie im Bsp1), wird die Variable mit den entsprechenden Werten importiert,
# wenn nein (wie bei Bsp2), wird die Variable dem Datensatz hinzugefügt und alle Beobachtungen sollen den Wert "nr" (nicht berichtet) erhalten.

write.csv2(DF,paste(Name_DF,"_neu.csv",sep=""),row.names=FALSE)
# 2. Das Abspechern des Datensatzes unter neuem Namen klappt. Aber wie erweitere ich die Funktion, dass der Datensatz auch direkt in den Workspace geladen wird?
}


import("Bsp1")
import("Bsp2")

Ich danke für Eure Hilfe!
Jörg

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

Re: Funktion zum Datenimport

Beitrag von bigben » Fr Sep 06, 2019 1:10 pm

Hallo Jörg,

zunächst
wie erweitere ich die Funktion, dass der Datensatz auch direkt in den Workspace gelade
Gar nicht. Das ist ganz schlechter Stil. Daten gehen in Funktionen als Argument hinein und aus Rückgabewert "return" heraus. Die Funktion wird um ein

Code: Alles auswählen

return(DF)
ergänzt, und damit was im Namespace ankommt wird sie aufgerufen mit

Code: Alles auswählen

Bsp1 <- import("Bsp1")
LG,
Bernhard
---
Programmiere stets so, dass die Maxime Deines Programmierstils Grundlage allgemeiner Gesetzgebung sein könnte

Jörg
Beiträge: 16
Registriert: Mi Nov 09, 2016 2:58 pm

Re: Funktion zum Datenimport

Beitrag von Jörg » Fr Sep 06, 2019 1:30 pm

Hallo Bernhard,

danke, das ist plausibel und ja auch eigentlich völlig simple.

Herzliche Grüße
Jörg

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

Re: Funktion zum Datenimport

Beitrag von jogo » Fr Sep 06, 2019 1:31 pm

Code: Alles auswählen

library("readr") 

import <- function(Name_DF) {
  df <- paste0(Name_DF,".csv")
  DF <- read_delim(df, ";", escape_double = FALSE, col_types = cols(Var1 = col_character(), Var2 = col_number(), Var3 = col_number()), trim_ws = TRUE)

  # 1. Es fehlt eine Abfrage, die überprüft, ob der zu importierende Datensatz eine bestimmte Variable mit Namen Namen "Var3" beinhaltet.
  #Wenn ja (wie im Bsp1), wird die Variable mit den entsprechenden Werten importiert,
  ### %%% in diesem Fall ist die Spalte bereits im Dataframe DF
  
  # wenn nein (wie bei Bsp2), wird die Variable dem Datensatz hinzugefügt und alle Beobachtungen sollen den Wert "nr" (nicht berichtet) erhalten.
  if (!("Var3" %in% names(DF))) DF$Var3 <- "nr"  ### %%% ich würde lieber  ... <- NA nehmen
  
  return(DF)
}

DFneu1 <- import("Bsp1")
DFneu2 <- import("Bsp2")
Gruß, Jörg

ruedi_br
Beiträge: 42
Registriert: Do Mär 01, 2018 3:53 pm

Re: Funktion zum Datenimport

Beitrag von ruedi_br » Fr Sep 06, 2019 1:37 pm

Sofern es sich immer um dieselbe Var3 handelt, war es das dann wohl, ansonsten sollte man wohl über eine "Masterliste" mit Variablennamen gehen und dann die Zeile

Code: Alles auswählen

if (!("Var3" %in% names(DF))) DF$Var3 <- "NA" 
in der Schleife verwenden ?
Aufgabenstellung war an dieser Stelle etwas unklar
Grüße
Ruedi

Code nachträglich korrigiert
Zuletzt geändert von ruedi_br am Mo Sep 09, 2019 4:28 pm, insgesamt 1-mal geändert.
fortune(111)

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

Re: Funktion zum Datenimport

Beitrag von bigben » Fr Sep 06, 2019 1:39 pm

Gut. Und ist das hier genug Hilfestellung für das andere Problem:

Code: Alles auswählen

test <- data.frame(a = 1:3, b = 1:3, c = 1:3)
print(test)

print(is.null(test$a))
print(is.null(test$d))

test$d <- NA
print(is.null(test$d))
print(test)
LG,
Bernhard

PS: ruedi war die entscheidende Minute schneller. Ohn Absprache haben wir beide NA anstelle von nr eingetragen, weil uns das idiomatischer erschien und auch bei Spalten aus Zahlen funktioniert. Lässt sich aber auch leicht adaptieren
---
Programmiere stets so, dass die Maxime Deines Programmierstils Grundlage allgemeiner Gesetzgebung sein könnte

Jörg
Beiträge: 16
Registriert: Mi Nov 09, 2016 2:58 pm

Re: Funktion zum Datenimport

Beitrag von Jörg » Sa Sep 07, 2019 6:36 pm

Bei mit funktioniert diese Zeile nicht

Code: Alles auswählen

if (!("Var3" in names(DF))) DF$Var3 <- "NA"
aber das geht:

Code: Alles auswählen

if (!("Var3" %in% names(DF))) DF$Var3 <- "NA"
Und so passt das dann alles, vielen Dank!

Wegen "nr": Da die Daten aus unterschiedlichen Quellen kommen, wollte ich zwei Arten von fehlenden Werten unterscheiden. "nr" wenn eine Variable im Quelldatensatz gar nicht erhoben wurde und NA dann, wenn sie grundsätzlich erhoben wurde, aber in einzelnen Fällen fehlt. Aber Bernhard hat natürlich recht, das wäre ein Problem mit numerischen Variablen. Da R ja nur NA für fehlende Werte kennt, muss ich das wohl über eine zusätzliche Variable lösen.

Jörg
Beiträge: 16
Registriert: Mi Nov 09, 2016 2:58 pm

Re: Funktion zum Datenimport

Beitrag von Jörg » Sa Sep 07, 2019 7:11 pm

Ich habe mal versucht die Idee mit der Masterliste umzusetzen, scheitere aber noch in dem Teil der Schleife, in dem die fehlende Variable kreiert und den Beobachtungen der Wert NA zugeordnet wird. Ich verstehe, warum das so nicht klappt, komme aber nicht auf die korrekte Lösung.

Code: Alles auswählen

import <- function(Name_DF){
  df <- paste0(Name_DF,".csv")
  DF <- read_delim(df, ";", escape_double = FALSE, col_types = cols(Var1 = col_character(), Var2 = col_number(), Var3 = col_number()), trim_ws = TRUE)
  Masterlist<-c("Var4","Var3")
  for (i in 1:length(Masterlist)){
  if (!(Masterlist[i] %in% names(DF))) paste0("DF$",Masterlist[i]) <- "NA" 
  }
  return(DF)
  }
Lg Jörg

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

Re: Funktion zum Datenimport

Beitrag von Athomas » Sa Sep 07, 2019 8:11 pm

Ich habe mir nicht den ganzen Fred durchgelesen, möchte aber anmerken, dass es in meinem Lieblingspackage "data.table" (neben einer großen Zahl anderer extrem nützlicher Features) die Funktion "rbindlist" gibt - die fehlende Variablen mit NA auffüllt (wenn man fill=TRUE vorgibt)!

Jörg
Beiträge: 16
Registriert: Mi Nov 09, 2016 2:58 pm

Re: Funktion zum Datenimport

Beitrag von Jörg » So Sep 08, 2019 8:45 am

Danke für den Hinweis mit data.table. Das löst mein eigentliches Problem natürlich auch. Ich hatte die Idee bereits beim Import der einzelnen Tabellen für eine einheitliche Struktur zu sorgen, und die Tabellen dann mit merge() zu verbinden und entsprechend meine Frage hier im Forum formuliert. Mit rbindlist löst man das Problem der unheitlichen Tabellen aber auch sehr elegant zu dem Zeitpunkt, wenn man die Tabellen verbindet.
Wie immer alles sehr lehrreich. :)
lg jörg

Antworten