Eine Loop mit zwei Bedingungen schreiben

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

Moderatoren: EDi, jogo

Antworten
FledermausR
Beiträge: 21
Registriert: Fr Mär 23, 2018 11:24 am

Eine Loop mit zwei Bedingungen schreiben

Beitrag von FledermausR »

Hallo,
ich habe versucht eine Loop zu schreiben. Kriege es aber nicht vollendet und bräuchte Hilfe. :?
Angenommen ich habe ein Dataset, hier jetzt eine ganz einfache Matrix, die Temperatur und Regendaten enthält

Code: Alles auswählen

temp<-c(1,2,3,4,5,6,7,8,9,10)
rain<-c(10,9,8,7,6,5,4,3,2,1)


Matrix<-cbind(temp,rain)
ich möchte die Bedingungen in einen Index poolen.
Wenn die Bedingung wahr ist, dass temp größer/gleich 7 ist UND rain kleiner gleich 3, dann soll index [ ] eine "1" bekommen.

index [ ] soll eine 0.5 bekommen, wenn die Temp zwischen 4 und 7 fällt oder rain zwischen 4 und 7 (wenn eine Bedingung zutrifft, soll es schon eine 0.5 bekommen, auch wenn die Andere auf den Fall mit index[ ]=1 fällt.
index [ ] soll eine 0 bekommen, wenn die temp unter 4 oder rain größer 7 ist.

das heißt z.b., das index[7] eine 0.5 bekommt, denn temp ist zwar bei 7, rain ist aber schon bei 4 usw.

Code: Alles auswählen

index<-(NA)

for(i in 1:nrow(Matrix))
{temp<-Matrix [i, "temp"]
       rain<-Matrix[i, "rain" ]
       if (temp[i]>=7 ) 
           if (rain[i] <=3){index[i]<-1}
        else if (temp[i]>=4 & temp[i] <7) 
          if (rain[i] >=4 & rain[i] <7) {index[i]<-0.5}
            else if (temp[i]<4)
              if (rain [i]>=7)  {index[i]<-0}

ich freue mich sehr über Hilfe.
Vielen Dank
bigben
Beiträge: 2781
Registriert: Mi Okt 12, 2016 9:09 am

Re: Eine Loop mit zwei Bedingungen schreiben

Beitrag von bigben »

Hallo FledermausR,

gleich die erste Zeile in Deiner for-Schleife macht etwas, womit Du wahrscheinlich nicht rechnest:

Code: Alles auswählen

> temp<-c(1,2,3,4,5,6,7,8,9,10)
> rain<-c(10,9,8,7,6,5,4,3,2,1)
> 
> 
> Matrix<-cbind(temp,rain)
> i <-  1
> temp<-Matrix [i, "temp"]
> temp
temp 
   1 
temp ist (in der geschweiften Klammer von for) immer nur ein einzelner Wert. Deshalb macht es keinen Sinn, später mit temp darauf zuzugreifen.

Code: Alles auswählen

if (temp[i]>=7 ) 
           if (rain[i] <=3){index[i]<-1}
Das ist eine komplizierte Möglichkeit, eine UND-Verknüpfung zu erstellen. Viel einfacher ist es mit diesem Operator:

Code: Alles auswählen

> TRUE & TRUE
[1] TRUE
> TRUE & FALSE
[1] FALSE
> FALSE & FALSE
[1] FALSE
> 
> temp <- c(1,2,3,4,5,6,7,8,9,10)
> rain <- c(10,9,8,7,6,5,4,3,2,1)
> temp[2] < 5 & rain[2] > 5
[1] TRUE
> temp[2] < 5 & rain[2] > 5
[1] TRUE
Dazu passend gibt es auch einen ODER-Operator:

Code: Alles auswählen

> TRUE | TRUE
[1] TRUE
> TRUE | FALSE
[1] TRUE
> 
> temp <- c(1,2,3,4,5,6,7,8,9,10)
> rain <- c(10,9,8,7,6,5,4,3,2,1)
> temp[2] < 5 | rain[2] < 5
[1] TRUE
Vielleicht findet sich auch hier eine gute Vorlage, an die Du Dich anlehnen kannst? viewtopic.php?p=10611#p10611

Kommst Du damit weiter?

LG,
Bernhard
---
Programmiere stets so, dass die Maxime Deines Programmierstils Grundlage allgemeiner Gesetzgebung sein könnte
FledermausR
Beiträge: 21
Registriert: Fr Mär 23, 2018 11:24 am

Re: Eine Loop mit zwei Bedingungen schreiben

Beitrag von FledermausR »

Hallo Bernhard,
vielen Dank für deine schnelle Antwort.
Ich habe den "und" (&) und "oder" (|) Operator versucht einzubringen.
Irgendwas mache ich trotzdem falsch.
Ich bekomme 11 Werte bei Index zurück, obwohl es nur 10 sein sollten.
Mein Beispiel für eine Spalte: (das Ergebnis sollte ja eigentlich so aussehen: 0 0 0 0 0.5 0.5 0.5 1 1 1)

Code: Alles auswählen

temp<-c(1,2,3,4,5,6,7,8,9,10)
rain<-c(10,9,8,7,6,5,4,3,2,1)

for(i in 1:10)if (temp[i]>=8){index[i]<-1}else if ( temp[i]<=7 & temp[i]>=5){index[i]<-0.5}else{index[i]<-0}
Außerdem weiß ich nicht, wie ich das auf 2 Spalten ausweiten soll (schaffe es ja nicht mal bei einer :oops: ).
Die Endversion der Loop soll sogar noch eine dritte Spalte mit Winddaten berücksichtigen.

Mein Ansatz für die Erweiterung auf zwei Spalten wäre folgender (klappt natürlich nicht)

Code: Alles auswählen

temp<-c(1,2,3,4,5,6,7,8,9,10)
rain<-c(10,9,8,7,6,5,4,3,2,1)


for(i in 1:10)if (temp[i]>=7 & rain [i]<4){index[i]<-1}else if (temp[i]>=4 & temp[i]<7 | rain [i]>=4 & rain [i]<7){index[i]<-0.5}else{index[i]<-0}
Bin sehr Dankbar für Hilfe.
LG
Bianca
bigben
Beiträge: 2781
Registriert: Mi Okt 12, 2016 9:09 am

Re: Eine Loop mit zwei Bedingungen schreiben

Beitrag von bigben »

Hallo Bianca,
FledermausR hat geschrieben: Do Okt 15, 2020 11:07 amIch bekomme 11 Werte bei Index zurück, obwohl es nur 10 sein sollten.
Das kann ich leider nicht reproduzieren und deshalb auch nicht korrigieren. Vielleicht braucht Dein Code einfach ein wenig Luft zum Atmen?
Ich hab mal index am Anfang initialisiert und ein paar Klammern und Zeilenumbrüche ergänzt, und jetzt läuft er mit vielversprechendem Ergebnis:

Code: Alles auswählen

index <- numeric(0)
temp <- c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
rain <- c(10, 9, 8, 7, 6, 5, 4, 3, 2, 1)

for(i in 1:10){
  if (temp[i] >= 8)
      { index[i] <- 1 }
  else if ( temp[i] <= 7 & temp[i] >=  5)
      { index[i]<- 0.5 }
  else 
      { index[i] <- 0 }
}
print(index)
Vielleicht versuchst Du, das noch für den Mehrspaltenfall auszubauen.

LG,
Bernhard
---
Programmiere stets so, dass die Maxime Deines Programmierstils Grundlage allgemeiner Gesetzgebung sein könnte
jogo
Beiträge: 2086
Registriert: Fr Okt 07, 2016 8:25 am

Re: Eine Loop mit zwei Bedingungen schreiben

Beitrag von jogo »

Hallo Bianca,

bitte immer schön vektorisiert arbeiten:

Code: Alles auswählen

Dat <- data.frame(temp=c(1,2,3,4,5,6,7,8,9,10), rain=c(10,9,8,7,6,5,4,3,2,1), index=NA)

# Wenn die Bedingung wahr ist, dass temp größer/gleich 7 ist UND rain kleiner gleich 3, 
#   dann soll index [ ] eine "1" bekommen.
Dat$index[with(Dat, temp>=7 & rain<=3)] <- 1

# index [ ] soll eine 0.5 bekommen, wenn die Temp zwischen 4 und 7 fällt oder rain zwischen 4 und 7 
#   (wenn eine Bedingung zutrifft, soll es schon eine 0.5 bekommen, 
#   auch wenn die Andere auf den Fall mit index[ ]=1 fällt.
Dat$index[with(Dat, (temp>=4 & temp<7) | (rain>4 & rain<=7))] <- 0.5

# index [ ] soll eine 0 bekommen, wenn die temp unter 4 oder rain größer 7 ist.
Dat$index[with(Dat, temp<4 | rain>7)] <- 0
Dat
Gruß, Jörg
FledermausR
Beiträge: 21
Registriert: Fr Mär 23, 2018 11:24 am

Re: Eine Loop mit zwei Bedingungen schreiben

Beitrag von FledermausR »

jippi klasse, jetzt klappts :lol:
Jetzt kann ich das ganze weiter entwickeln (hoffe ich XD)
Vielen Dank Bernhard und Jörg
LG
Antworten