Seite 1 von 1

if-Abfrage - einfacherer Aufbau

Verfasst: Mo Nov 19, 2018 11:01 am
von jessi
Liebe Forum-Mitglieder,

meine derzeitige if-Abfrage ist sehr lange bzw. wiederholen sich die Abfragen und nur der zugeordnete Werte ändert sich:

Code: Alles auswählen

library(raster)
r_OH <- raster("ohio_area_class.tiff")
h_OH <- raster("ohio_height.tiff")

f2 <- function(x,y){
 ifelse( x == 114 & y < 300, 2, 
 ifelse( x == 114 & y > 300 & y < 599, 1, 
 ifelse( x == 114 & y > 600 & y < 899, 1, 
 ifelse( x == 114 & y > 900 & y > 1199, 1,
 ifelse( x == 114 & y > 1200, 1, 

 ifelse( x == 120 & y < 300, 2, 
 ifelse( x == 120 & y > 300 & y < 599, 1, 
 ifelse( x == 120 & y > 600 & y < 899, 1, 
 ifelse( x == 120 & y > 900 & y > 1199, 1,
 ifelse( x == 120 & y > 1200, 1,

 ifelse( x == 1190 & y < 300, 3, 
 ifelse( x == 1190 & y > 300 & y < 599, 3, 
 ifelse( x == 1190 & y > 600 & y < 899, 3, 
 ifelse( x == 1190 & y > 900 & y > 1199, 1,
 ifelse( x == 1190 & y > 1200, 1,

 ....

 ifelse (x == 1200, 0, 
 ifelse (x == 1210, 0, 
 ifelse (x == 1220, 0, 
 ifelse (y > 1500, 0,

NA  ))))) ))))) ))))) ... )))) }

rr_neu <- overlay(s_OH, h_OH, fun = f2)

Insgesamt gibt es mehrere solcher if-Blöcke. Die tiff.files "ohio_area_class.tiff" enthält Bodenklassen mit den Werten von x (113, 114, ...), "ohio_height.tiff" die Höhe in Meter. Mit meiner if-Abfrage möchte ich die Anzahl von Tornados in Kategorien (0 bis 3) zuordnen und zwar in Abhängigkeit von Bodenklasse und Höhe. Als rr_neu erhalte ich ein neues Rasterfile, dass die Werte 0 bis 3 enthalten. Es funktioniert alles wunderbar, nur möchte ich jetzt gerne etwas effizienter und kompakter zusammenfassen, da ich diese Auswertungen für mehrere US-Staaten machen soll und dann gleich mal ein Code mit tausend Zeilen zusammen kommt.

Probiert habe ich folgendes:
Zuerst habe ich die Daten in einen extra data.frame geschrieben und dann versucht mit der sapply-Funktion die vielen if-Abfragen zusammenzufassen.

Code: Alles auswählen

class <- c(114,114,114,114,114,120,120,120,120,120,1190,1190,1190,1190,1190)
kat <- c(2,1,1,1,1,2,1,1,1,1,3,3,3,1,1)
df <- data.frame(class,kat)
str(df)
   class kat
1    114   2
2    114   1
3    114   1
4    114   1
5    114   1
6    120   2
7    120   1
8    120   1
9    120   1
10   120   1
11  1190   3
12  1190   3
13  1190   3
14  1190   1
15  1190   1

z <- unique(df$class)
f <- function(kat) {df$kat[sapply(z, function(x) which(x==df$class))]}
[1] 2 1 1 1 1 2 1 1 1 1 3 3 3 1 1

Allerdings weiß ich nicht, wie ich am besten die Höhenbedingungen (zB. größer 300 und kleiner 599) einbauen soll.

Danke für eure Hilfe :)
Jessi

Re: if-Abfrage - einfacherer Aufbau

Verfasst: Mo Nov 19, 2018 11:47 am
von jogo
Hallo Jessi,

zumindest ist in dem bisherigen Code ein Schreibfehler; ifelse( ... & y > 900 & y > 1199, 1, muss wohl heißen

Code: Alles auswählen

 ifelse( ... & y > 900 & y < 1199, 1,
Gruß, Jörg
p.s.: schau mal, ob Du die Funktion cut() verwenden möchtest.

Re: if-Abfrage - einfacherer Aufbau

Verfasst: Mo Nov 19, 2018 12:20 pm
von Athomas
Ich würde eine Hilfsvariable für die Höhenklassen erzeugen (mit "cut", wie jogo vorgeschlagen hat, dabei die Paraneter "right" und "labels" sinnvoll wählen), eine Übersetzungstabelle (Bodenklasse, Höhenklasse) -> Rasterwert definieren, und die dann an die erste Datei anmergen...

Die Schreibarbeit hast Du dann bei der Erstellung der Übersetzungstabelle - da läßt sich doch wahrscheinlich was automatisieren!?

Wenn Du ganz raffiniert sein willst, geht es wahrscheinlich auch ohne die Hilfsvariable mit einem "rolling join" von data.table - aber das lassen wir hier besser :D ...

Re: if-Abfrage - einfacherer Aufbau

Verfasst: Mo Nov 19, 2018 7:41 pm
von EDi
Athomas hat geschrieben: Mo Nov 19, 2018 12:20 pm Wenn Du ganz raffiniert sein willst, geht es wahrscheinlich auch ohne die Hilfsvariable mit einem "rolling join" von data.table - aber das lassen wir hier besser :D ...
Nein, nicht lassen. Wäre an einem Beispiel davon interessiert, hab bisher keine Verwendung für gefunden gehabt...

Re: if-Abfrage - einfacherer Aufbau

Verfasst: Mo Nov 19, 2018 7:46 pm
von EDi

Code: Alles auswählen

ifelse( x == 114 & y < 300, 2, 
 ifelse( x == 114 & y > 300 & y < 599, 1, 
 ifelse( x == 114 & y > 600 & y < 899, 1, 
 ifelse( x == 114 & y > 900 & y > 1199, 1,
 ifelse( x == 114 & y > 1200, 1, 
 
Ist das nicht das gleiche wie

Code: Alles auswählen

ifelse( x == 114 & y < 300, 2, 1)
:?:

[Was ist mit y ==300?]

Was ist die Regel dahinter? Kannst du das auch in Prosa formulieren?

Re: if-Abfrage - einfacherer Aufbau

Verfasst: Mo Nov 19, 2018 8:40 pm
von Athomas
Nein, nicht lassen. Wäre an einem Beispiel davon interessiert, hab bisher keine Verwendung für gefunden gehabt...
Ich halte das für kein gutes Beispiel und werde versuchen, bei Gelegenheit etwas Passenderes nachzureichen:

Code: Alles auswählen

library(openxlsx)
library(data.table)

Messungen  <- data.table(read.xlsx("D:/R/R Forum/Tornados/Daten.xlsx", sheet="Messungen"))
setkey(Messungen,Bodenklasse,Höhe)
Kategorien <- data.table(read.xlsx("D:/R/R Forum/Tornados/Daten.xlsx", sheet="Kategorien"))
Kategorien[  , Höhe:=ab_Höhe]   # ist nicht wesentlich, nur damit die gemessene Höhe ihren Namen behält!
setkey(Kategorien,Bodenklasse,Höhe)

Kategorien[Messungen, roll=TRUE]

Re: if-Abfrage - einfacherer Aufbau

Verfasst: Di Nov 20, 2018 12:11 pm
von Athomas
Ich ... werde versuchen, bei Gelegenheit etwas Passenderes nachzureichen
Folgenden Blog-Artikel zum Thema "rolling joins" finde ich ganz schön: https://gormanalysis.com/r-data-table-rolling-joins/