for schleife für CASE WHEN THEN

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

Moderatoren: EDi, jogo

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

for schleife für CASE WHEN THEN

Beitrag 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
Benutzeravatar
EDi
Beiträge: 1599
Registriert: Sa Okt 08, 2016 3:39 pm

Re: for schleife für CASE WHEN THEN

Beitrag 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.
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.
janedoe

Re: for schleife für CASE WHEN THEN

Beitrag 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
Benutzeravatar
EDi
Beiträge: 1599
Registriert: Sa Okt 08, 2016 3:39 pm

Re: for schleife für CASE WHEN THEN

Beitrag 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.
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: for schleife für CASE WHEN THEN

Beitrag 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
jessi
Beiträge: 100
Registriert: Mo Jul 10, 2017 9:23 am

Re: for schleife für CASE WHEN THEN

Beitrag von jessi »

hallo nochmals,

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

grüße,
Jessi
bigben
Beiträge: 2771
Registriert: Mi Okt 12, 2016 9:09 am

Re: for schleife für CASE WHEN THEN

Beitrag 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
---
Programmiere stets so, dass die Maxime Deines Programmierstils Grundlage allgemeiner Gesetzgebung sein könnte
jessi
Beiträge: 100
Registriert: Mo Jul 10, 2017 9:23 am

Re: for schleife für CASE WHEN THEN

Beitrag 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
bigben
Beiträge: 2771
Registriert: Mi Okt 12, 2016 9:09 am

Re: for schleife für CASE WHEN THEN

Beitrag von bigben »

SQLite bezeichnet fehlende Daten als NULL, nicht als 0:
https://www.tutorialspoint.com/sqlite/s ... values.htm
LG,
Bernhard
---
Programmiere stets so, dass die Maxime Deines Programmierstils Grundlage allgemeiner Gesetzgebung sein könnte
Antworten