Seite 1 von 1

for schleife für CASE WHEN THEN

Verfasst: Di Aug 29, 2017 3:46 pm
von jessi
Schönen Nachmittag,

ich möchte gewisse Werte in meiner DB zählen und habe dazu folgenden Code

Code: Alles auswählen

count <- dbGetQuery(conn, 'SELECT
	      		  CASE WHEN (T >=10 AND T < 15) THEN 1
	      		           WHEN (T >=15 AND phi < 20) THEN 2
			           WHEN T < 0 THEN 3 
                                    ELSE 999
			       END AS bin,
			   count(1) as count
	      FROM data
	        AND phi >= 48 AND phi < 49
	       AND lam ==  16.2
	     GROUP by bin;')
	     
print(count)
bin	count
1	8063
2	6186
	    
So weit funktioniert das Zählen schon mal. Jetzt habe ich allerdings sehr viele phi und lam Werte und ich möchte die Auslese-Routine nicht immer aufs neue Starten. Darum war der Plan eine for Schleife zu bauen - leider funktioniert das nicht so ganz.

Code: Alles auswählen

p1 <- c(48, 49, 50)
p2 <- c(49, 50, 51)
l <- c(16.2, 16.4, 16.6)

for (i in 1:3)
count <- dbGetQuery(conn, 'SELECT
	      		  CASE WHEN (T >=10 AND T < 15) THEN 1
	      		           WHEN (T >=15 AND phi < 20) THEN 2
			           WHEN T < 0 THEN 3 
                                    ELSE 999
			       END AS bin,
			   count(1) as count
	      FROM data
	        AND phi >= p1[i] AND phi < p2[i]
	       AND lam ==  l[i]
	     GROUP by bin;')
	     
 Error in rsqlite_send_query(conn@ptr, statement) :
  near "ND": syntax error     
Kann mir vielleicht jemand sagen, wo genau der Fehler liegt?
Bzw. ist es möglich, zur Ausgabe von count zusätzlich auch p1 und p2 sowie l anzugeben?

Danke und glg.
J

Re: for schleife für CASE WHEN THEN

Verfasst: Di Aug 29, 2017 11:14 pm
von EDi
Kann mir vielleicht jemand sagen, wo genau der Fehler liegt?

Code: Alles auswählen

'SELECT
	      		  CASE WHEN (T >=10 AND T < 15) THEN 1
	      		           WHEN (T >=15 AND phi < 20) THEN 2
			           WHEN T < 0 THEN 3 
                                    ELSE 999
			       END AS bin,
			   count(1) as count
	      FROM data
	        AND phi >= p1[i] AND phi < p2[i]
	       AND lam ==  l[i]
	     GROUP by bin;'
Ist ein fixer character, d.h er ändert sich nciht mit der Schleife und p1 und p2 werden auch nicht aufgelöst.

Lösung?
Entweder mit paste() arbeiten (dann wird p1 aufgelöst) oder mit dplyr und filter() die query erstellen (https://db.rstudio.com/dplyr/).

Zweiteres empfinde ich derzeit als sehr angenehm mit zu arbeiten.

Re: for schleife für CASE WHEN THEN

Verfasst: Mi Aug 30, 2017 4:13 pm
von janedoe
Hallo,

danke für deine Antwort. Ich habe jetzt den Ansatz mit paste() probiert.

Code: Alles auswählen

for (i in 1:3)
count <- dbGetQuery(conn, paste('SELECT
	      		  CASE WHEN (T >=10 AND T < 15) THEN 1
	      		           WHEN (T >=15 AND phi < 20) THEN 2
			           WHEN T < 0 THEN 3 
                                    ELSE 999
			       END AS bin,
			   count(1) as count
	      FROM data
	        WHERE phi >= p1(i) AND phi < p2(i)
	       AND lam ==  l(i)
	     GROUP by bin;'))
	     
Fehler in rsqlite_send_query(conn@ptr, statement) : no such column: i	     
Jetzt bekomme ich die Fehlermeldung, dass es i nicht gibt. Wenn ich in anderer Weise auf az und r zugreifen, bekomme ich keine Werte mehr?

Code: Alles auswählen

for (i in 1:3)
count <- dbGetQuery(conn, paste('SELECT
	      		  CASE WHEN (T >=10 AND T < 15) THEN 1
	      		           WHEN (T >=15 AND phi < 20) THEN 2
			           WHEN T < 0 THEN 3 
                                    ELSE 999
			       END AS bin,
			   count(1) as count
	      FROM data
	        WHERE (phi >= ",p1[i],") AND (phi < ",p2[i],")
	       AND (lam ==  ",l[i],")
	     GROUP by bin;'))
	     
count
[1] bin   count
<0 Zeilen> (oder row.names mit Länge 0)
 


Grüße,
Jess

Re: for schleife für CASE WHEN THEN

Verfasst: Mi Aug 30, 2017 9:15 pm
von EDi
Zur einer for-schleife gehören immer geschweifte Klammern!

Einpaar wenige Ausnahmen (sonst immer):
Bei if() kann man diese weglassen, falls es sich um einen Einzeiler handelt.
Bei function() falls diese in der selben zeile steht.

Re: for schleife für CASE WHEN THEN

Verfasst: Do Aug 31, 2017 7:57 pm
von jessi
Hallo,

meinen Sie geschwungene Klammern in dieser Art?

Code: Alles auswählen

for (i in 1:3){
count <- dbGetQuery(conn, paste('SELECT
	      		  CASE WHEN (T >=10 AND T < 15) THEN 1
	      		           WHEN (T >=15 AND phi < 20) THEN 2
			           WHEN T < 0 THEN 3 
                                    ELSE 999
			       END AS bin,
			   count(1) as count
	      FROM data
	        WHERE (phi >= ",p1[i],") AND (phi < ",p2[i],")
	       AND (lam ==  ",l[i],")
	     GROUP by bin;'))}
Zwar bekomme ich so keine Fehlermeldung, das Ergebnis ist aber wieder

Code: Alles auswählen

count
[1] bin   count
<0 Zeilen> (oder row.names mit Länge 0)
Irgendwie blick ich da nicht mehr durch :?:

Grüße,
Jessi

Re: for schleife für CASE WHEN THEN

Verfasst: Do Aug 31, 2017 8:42 pm
von jessi
hallo nochmals,

kann ich die Abfrage auch irgendwie ohne for-Schleife machen?

grüße,
Jessi

Re: for schleife für CASE WHEN THEN

Verfasst: Do Aug 31, 2017 8:54 pm
von bigben
Hi!

Ohne die Datenbank kann von uns natürlich niemand den Code laufen lassen und sehen, was passiert. Das sind ja auch eine ganze Reihe von Bedingungen, die da erfüllt werden sollen. Insbesondere der Vergleich von Fließkommazahlen mit '==' ist ja sehr oft eine gefährliche Sache.

Was man von hier aus raten kann, ist dbGetQuery mal durch ein einfaches print oder cat zu ersetzen. Dann siehst Du den exakten SQL-Code, der an die Datenbank geschickt wird und kannst schauen, ob es wirklich Daten gibt, die dazu passen:

Code: Alles auswählen

for (i in 1:3){
count <- cat(paste('SELECT
	      		  CASE WHEN (T >=10 AND T < 15) THEN 1
	      		           WHEN (T >=15 AND phi < 20) THEN 2
			           WHEN T < 0 THEN 3 
                                    ELSE 999
			       END AS bin,
			   count(1) as count
	      FROM data
	        WHERE (phi >= ",p1[i],") AND (phi < ",p2[i],")
	       AND (lam ==  ",l[i],")
	     GROUP by bin;'))
}
Wenn Du diesen Code laufen lässt, dann merkst Du schnell, dass p1 etc gar nicht ersetzt werden, sondern so stehen bleiben.

Das liegt an dem Durcheinander mit zwei verschiedenen Sorten Anführungszeichen! Versuch mal

Code: Alles auswählen

for (i in 1:3){
    count <- cat(paste("SELECT
                       CASE WHEN (T >=10 AND T < 15) THEN 1
                       WHEN (T >=15 AND phi < 20) THEN 2
                       WHEN T < 0 THEN 3 
                       ELSE 999
                       END AS bin,
                       count(1) as count
                       FROM data
                       WHERE (phi >= ",p1[i],") AND (phi < ",p2[i],")
                       AND (lam ==  ",l[i],")
                       GROUP by bin;\n"))
}
Und dann schau Dir an, ob dieses SQL etwas taugt.

LG,
Bernhard

Re: for schleife für CASE WHEN THEN

Verfasst: Fr Sep 01, 2017 8:37 pm
von jessi
Hallo,

wenn ich die Anführungszeichen ändere funktioniert es, vielen Dank.

Auf die Gefahr hin, dass die Frage hier jetzt falsch platziert ist: beim Auszählen einiger lam und phi werte ist mir aufgefallen, dass wenn kein T-Wert gefunden wurde, diese Kategorie auch nicht als 0 ausgegeben wird. Kann ich mir auch 0-Werte ausgeben lassen, damit die Vergleichbarkeit gewährleistet bleibt? Sorry, falls das hier die falsche Kategorie ist.

grüße,
jessi

Re: for schleife für CASE WHEN THEN

Verfasst: Sa Sep 02, 2017 12:40 pm
von bigben
SQLite bezeichnet fehlende Daten als NULL, nicht als 0:
https://www.tutorialspoint.com/sqlite/s ... values.htm
LG,
Bernhard