Daten schneller einlesen

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

Moderatoren: EDi, jogo

Antworten
jessi
Beiträge: 100
Registriert: Mo Jul 10, 2017 9:23 am

Daten schneller einlesen

Beitrag von jessi »

Hallo zusammen,

ich habe vielleicht eine etwas komische Frage, bin aber leider in Google bzw. diversen Skripten nicht recht viel schlauer geworden. Ich habe wirklich sehr sehr viele Messdaten. Diese einzulesen dauert nun sehr lange bzw. kommt als R-Meldung Error: cannot allocate vector of size xxx Mb. Gibt es eine Lösung, die Messdaten ev. "schneller" einzulesen bzw. meinen memory.size zu erhöhen um überhaupt mit den vielen Messdaten Auswertungen zu machen?

Mein bisheriger Code:

Code: Alles auswählen

library(RSQLite)
m <- dbDriver("SQLite")

con <- dbConnect(m, dbname = "messdaten"')

alltables <- dbListTables(con)
alltables

# bei dieser Zeile kommt dann nach einiger Zeit die oben beschriebene Fehlermeldung
daten <- dbGetQuery(con, 'SELECT datum a r e v FROM data_wind')
Ich hab mal gelesen, dass man Matrizen (mit Null befüllt) vorher schon definierten sollte, da dies den Einleseprozess beschleunigen soll. Die Matrix mit den Messdaten würde ich wie folgt definieren:

Code: Alles auswählen

daten <- matrix(0, ncol=10000, nrow=10000)
Leider weiß ich die genau Größe (col & row) der Matrix "daten" nicht, da diese von der Zeit abhängt, also mal lese ich die Daten von 5 Tagen ein, dann wieder von 17 Tagen bzw. nur von einem.
Gibt es vielleicht noch andere Möglichkeiten oder ist die Methode der Nullmatrix die ich hier mal als ev. Lösung annehme überhaupt richtig.

Vielen Lieben dank für Lösungsvorschläge,
J
Benutzeravatar
student
Beiträge: 674
Registriert: Fr Okt 07, 2016 9:52 am

Re: Daten schneller einlesen

Beitrag von student »

Hallo Jessi,

ich denke, Du hast ein Speicherplatzproblem. Kannst Du die Daten sequenziell einlesen? Schau mal hier!
Viele Grüße,
Student
-----------------------------------------------------------------------------------------------------------------------
faes.de, Datenanalyse mit R & das Ad-Oculos-Projekt
Das Ad-Oculos-Projekt auf YouTube

Habe Mut, dich deines eigenen Verstandes zu bedienen! (Kant)
jessi
Beiträge: 100
Registriert: Mo Jul 10, 2017 9:23 am

Re: Daten schneller einlesen

Beitrag von jessi »

Hallo Student,

vielen Dank für deine Antwort. Ich habe jetzt folgendes probiert:

Code: Alles auswählen

library(RODBC)
library(ff)
library(ETLUtils)  

x <- read.dbi.ffdf(query = "SELECT * FROM data", dbConnect.args = list(drv = dbDriver("SQLite"), dbname = 'messdaten'),VERBOSE=TRUE)


Output

Code: Alles auswählen

ffdf (all open) dim=c(1656994,10), dimorder=c(1,2) row.names=NULL
ffdf virtual mapping
            PhysicalName VirtualVmode PhysicalVmode  AsIs VirtualIsMatrix PhysicalIsMatrix PhysicalElementNo
Zeitstempel  Zeitstempel      integer       integer FALSE           FALSE            FALSE                 1
Datum              Datum      integer       integer FALSE           FALSE            FALSE                 2
Stunde            Stunde      integer       integer FALSE           FALSE            FALSE                 3
Minute            Minute      integer       integer FALSE           FALSE            FALSE                 4
p                    p      integer       integer FALSE           FALSE            FALSE                 5
l              l      integer       integer FALSE           FALSE            FALSE                 6
v                v     integer       integer FALSE           FALSE            FALSE                 7
u         u      integer       integer FALSE           FALSE            FALSE                 8
w      w      integer       integer FALSE           FALSE            FALSE                 9
g        g      integer       integer FALSE           FALSE            FALSE                10
            PhysicalFirstCol PhysicalLastCol PhysicalIsOpen
Zeitstempel                1               1           TRUE
Datum                      1               1           TRUE
Stunde                     1               1           TRUE
Minute                     1               1           TRUE
p                         1               1           TRUE
l                      1               1           TRUE
v                      1               1           TRUE
u                    1               1           TRUE
w                  1               1           TRUE
g                   1               1           TRUE
ffdf data
        Zeitstempel        Datum       Stunde       Minute           p        l        v    u
1      201703130000 20170313     0            0           47       7            0                      
2      201703130000 20170313     0            0            47          8           0                      
3      201703130000 20170313     0            0            47          9            3                      
4      201703130000 20170313     0            0            47          10           24                      
                
:                 :            :            :            :            :            :            :            :
                  
165695 201703152355 20170315     23           55           57       14           7                     
165696 201703152355 20170315     23           55           57          15          10                      
165697 201703152355 20170315     23           55           57          16          36                     
165698 201703152355 20170315     23           55          57         17          14                      
165699 201703152355 20170315     23           55          57         18          2                      
             w                        g
1                               
2                               
3                               
4                               
5                               
6                               
7                               
8                               
:                 :            :
165692                          
165693                          
165694                          
165695                          
165696                          
165697                          
165698                          
165699                          
Leider werde ich aus dem Output nicht so recht schlau. Werden jetzt alle Daten eingelesen und kann ich diese "normal" weiter bearbeiten oder muss ich zusätzlich was berücksichtigen?

Wenn ich die Daten weiter bearbeite, beispielsweise.

Code: Alles auswählen

daten <- subset(x, x$p >= 45 & x$p <=48)
bekomme ich eine

Code: Alles auswählen

ffdf (all open) dim=c(165699,0), dimorder=c(1,2) row.names=NULL
ffdf virtual mapping
 [1] PhysicalName      VirtualVmode      PhysicalVmode     AsIs              VirtualIsMatrix  
 [6] PhysicalIsMatrix  PhysicalElementNo PhysicalFirstCol  PhysicalLastCol   PhysicalIsOpen   
<0 Zeilen> (oder row.names mit Länge 0)
ffdf data
[1] "[empty matrix]"

Ich glaube auch, dass die Werte als factor rausgeschrieben werden?

glg.
Jess
Benutzeravatar
EDi
Beiträge: 1599
Registriert: Sa Okt 08, 2016 3:39 pm

Re: Daten schneller einlesen

Beitrag von EDi »

Wie student schon schrieb hast du ein Speicherplatzproblem.

Wenn die 'weiterverarbeitung' nur aus subsets etc besteht, würde ich das auf der Datenbank machen und nicht in R (in SQL wäre das ein WHERE ).

Für DB-R interaktionen gibt es auch das neue/überarbeitetet DBI package.
Bitte immer ein reproduzierbares Minimalbeispiel angeben. Meinungen gehören mir und geben nicht die meines Brötchengebers wieder.

Dieser Beitrag ist lizensiert unter einer CC BY 4.0 Lizenz
Bild.
jessi
Beiträge: 100
Registriert: Mo Jul 10, 2017 9:23 am

Re: Daten schneller einlesen

Beitrag von jessi »

Hallo.

Leider besteht die Weiterverarbeitung nicht nur aus subset-Abfragen. Allerdings scheitere ich schon beim Einlesen der Daten. Gibt es sonst keine Möglichkeit viele Daten einzulesen?

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

Re: Daten schneller einlesen

Beitrag von jogo »

Hallo Jessi,
jessi hat geschrieben: So Jul 23, 2017 12:11 pm
ich habe vielleicht eine etwas komische Frage, bin aber leider in Google bzw. diversen Skripten nicht recht viel schlauer geworden. Ich habe wirklich sehr sehr viele Messdaten. Diese einzulesen dauert nun sehr lange bzw. kommt als R-Meldung Error: cannot allocate vector of size xxx Mb. Gibt es eine Lösung, die Messdaten ev. "schneller" einzulesen bzw. meinen memory.size zu erhöhen um überhaupt mit den vielen Messdaten Auswertungen zu machen?
Hier wird dieses Problem breit diskutiert: https://stackoverflow.com/questions/517 ... -size-n-mb
Eine Kurzversion, die die möglichen Lösungen beschreibt ist:

Code: Alles auswählen

library("fortunes")
fortune(192)
Mein bisheriger Code:

Code: Alles auswählen

library(RSQLite)
m <- dbDriver("SQLite")

con <- dbConnect(m, dbname = "messdaten"')

alltables <- dbListTables(con)
alltables

# bei dieser Zeile kommt dann nach einiger Zeit die oben beschriebene Fehlermeldung
daten <- dbGetQuery(con, 'SELECT datum a r e v FROM data_wind')
Ich hab mal gelesen, dass man Matrizen (mit Null befüllt) vorher schon definierten sollte, da dies den Einleseprozess beschleunigen soll. Die Matrix mit den Messdaten würde ich wie folgt definieren:

Code: Alles auswählen

daten <- matrix(0, ncol=10000, nrow=10000)
Diese Lösung ("preallocation of a matrix/vector") trifft für Dich nicht zu.
preallocation ist immer dann hilfreich, wenn ansonsten ein Vektor (bzw. eine Matrix) Stück für Stück aufgebaut (und dabei ständig vergrößert) wird. In Deinem Fall bekommst Du durch die Datenbankabfrage einen kompletten Dataframe.

Neben allem, was schon geschrieben wurde, könnte es noch die Möglichkeit geben, möglichst viel Arbeit schon auf der Seite der Datenbank zu erledigen:
a) also entweder direkt in SQLite oder
b) in einer anderen Datenbank (dafür müssen die Daten natürlich erst migriert werden).
Dort müsste mindestens eine Stufe der Aggregation der Daten erfolgen, um die Datenmenge zu reduzieren.

Folgende Fragen nebenbei:
Wieviel RAM hat Dein Computer?
Welches Betriebssystem verwendest Du? (insbesondere 32-bit oder 64-bit?)
Welche Version von R verwendest Du? (auch hier wieder: insbesondere 32-bit oder 64-bit?)

Gruß, Jörg
jessi
Beiträge: 100
Registriert: Mo Jul 10, 2017 9:23 am

Re: Daten schneller einlesen

Beitrag von jessi »

Hallo zusammen,

vielen Dank für eure Antworten. Ich probiere jetzt einen anderen Zugang und zwar die Daten schon vor der query-Abfrage entsprechend zu filtern. Leider geht das auch nur mit R, da ich keinen direkten Zugriff auf die db habe.
Das ganze möchte ich jetzt mitteln for-Schleifen machen und ich muss gestehen, vor lauter R blicke ich nicht mehr durch.
Ich brauche insgesamt drei for-Schleifen, da ich drei Bedingungen an die Daten stelle (die Datumszuweisung, Längen- und Breitengrade).
Das ganze habe ich jetzt mal so zu lösen versucht.

Code: Alles auswählen

#sql einlesen 
library(RSQLite)
m <- dbDriver("SQLite")
con <- dbConnect(m, dbname = "messdaten"')
alltables <- dbListTables(con)
alltables

#Einschränken der Daten 
for (Tag in c('20140101', '20140113', '20140131')) {
	for (p in subset(48, 53))
		for (l in subset(8, 15))
			
			daten <- paste("SELECT p, l, v",  
					 "FROM data",
				         "WHERE (Tag = Tag)", 
				          "AND (p = p)",
					  "AND (l = l)"}
Irgendwo hab ich aber einen Denkfehler drinnen, beim Schleifenbau. Als Fehlermeldung bekomme ich

Code: Alles auswählen

Fehler: Unerwartete(s) '}' in:
" "AND (p = p)",
 "AND (l = l)"}"
Ich muss nochmals um eure Hilfe bitte :?

Danke vielmals. Jess
Benutzeravatar
EDi
Beiträge: 1599
Registriert: Sa Okt 08, 2016 3:39 pm

Re: Daten schneller einlesen

Beitrag von EDi »

Das sieht mir viel zu kompliziert aus... Liest dich bitte noch ein wenig in SQL ein (das Problem hat wenig mit R zu tun): da gibt es ein 'IN' operator...
Bitte immer ein reproduzierbares Minimalbeispiel angeben. Meinungen gehören mir und geben nicht die meines Brötchengebers wieder.

Dieser Beitrag ist lizensiert unter einer CC BY 4.0 Lizenz
Bild.
jogo
Beiträge: 2086
Registriert: Fr Okt 07, 2016 8:25 am

Re: Daten schneller einlesen

Beitrag von jogo »

Hallo Jessi,
jessi hat geschrieben: Mo Jul 24, 2017 2:05 pm Irgendwo hab ich aber einen Denkfehler drinnen, beim Schleifenbau. Als Fehlermeldung bekomme ich

Code: Alles auswählen

Fehler: Unerwartete(s) '}' in:
" "AND (p = p)",
 "AND (l = l)"}"
es muss am Ende heißen: "AND (l = l)")} (die schließende runde Klamme ist das Gegenstück zu der öffnenden beim Aufruf der Funktion paste )

Gruß, Jörg
jessi
Beiträge: 100
Registriert: Mo Jul 10, 2017 9:23 am

Re: Daten schneller einlesen

Beitrag von jessi »

Hallo.

Jetzt habe ich noch was anderes probiert:

Code: Alles auswählen

i <- dbGetQuery(con, 'SELECT datum, a, r, e, v, FROM wind WHERE data_wind in datum (20140401) AND p = :x AND range = :y', params = list(x=seq(48,53), y = seq(1800,2200,200)))
Hier funktioniert die letzte Abfrage y=seq(1800,2200,200) nicht. Gibt es hier einen Trick, wie ich R sage, dass y eine Schrittweite von 200 hat?

Danke für eure Mithilfe!!

Jessi
Antworten