Windrichtung berechnen, for loop

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

Moderatoren: EDi, jogo

ExpectoPatronum
Beiträge: 9
Registriert: Fr Jul 03, 2020 10:44 am

Windrichtung berechnen, for loop

Beitrag von ExpectoPatronum »

Hallo zusammen,
Ich muss über einen Loop die Windrichtung bestimmen.
Ich habs wenigstens schon geschafft für die erste Spalte die Rechnung durchlaufen zu lassen, allerdings soll das für insgesamt 60 Spalten funktionieren. Und da ist der Punkt an dem ich hänge.. Kann mir jemand von euch vllt. helfen?
Die Daten kommen aus zwei Tabellen (UData005, VData005)

Code: Alles auswählen


new005 <- list()

for (i in 1:42) {
  
  alpha005 <- (atan(abs(UData005[i,1])/abs(VData005[i,1])))*(180/pi)
  
  if(is.na(UData005[i,1]) || is.na(VData005[i,1])){
    new005[i] <- NA
  } else {
    if(UData005[i,1] >= 0 && VData005[i,1] >= 0){
      new005[i] <- alpha005+180
    } else { 
      if(UData005[i,1] >= 0 && VData005[i,1] < 0){
        new005[i] <- (180-alpha005) +180
      } else {
        if (UData005[i,1] < 0 && VData005[i,1] >= 0){
          new005[i] <- (360-alpha005)-180
        } else {
          if(UData005[i,1] < 0 && VData005[i,1] < 0){
            new005[i] <- (180+alpha005)-180
          } 
        }
      }
    }
  }
}
bigben
Beiträge: 2771
Registriert: Mi Okt 12, 2016 9:09 am

Re: Windrichtung berechnen, for loop

Beitrag von bigben »

Hi!

Die Spalte hast Du in Deinem Code überall da fest codiert, wo ,1] steht. Wenn Du statt dieser 1 eine Variable j einsetzt, dann wird Dein Code gleich viel flexibler. Du kannst dann entweder manuell j <- 1 setzen oder j <- 2 oder eine for-Schleife um Deinen bisherigen Code schreiben

Code: Alles auswählen

for(j in 1:60){
    new005 <- list()

    for (i in 1:42) {
  
      alpha005 <- (atan(abs(UData005[i,1])/abs(VData005[i,1])))*(180/pi)
      # ...
      }
}
Dann musst Du noch gucken, dass new005 nicht ständig überschrieben wird, dazu hab ich hier mal was gemacht: viewtopic.php?f=20&t=30

HTH,
Bernhard
---
Programmiere stets so, dass die Maxime Deines Programmierstils Grundlage allgemeiner Gesetzgebung sein könnte
ExpectoPatronum
Beiträge: 9
Registriert: Fr Jul 03, 2020 10:44 am

Re: Windrichtung berechnen, for loop

Beitrag von ExpectoPatronum »

Vielen Dank schonmal für deine Antwort.
Leider bin ich nicht sehr versiert in R und muss sagen, dass ich nicht weiß wie ich das aus deinem anderen Eintrag ausführen kann. :lol:
Ist das so richtig auch in new005[] in die Klammern [i,j] zu schreiben?
Mir wird nämlich bei folgendem Code ein Error angegeben: Fehler in new005[i, j] <- alpha005 + 180 : falsche Anzahl von Indizes für Matrix

Code: Alles auswählen

for (j in 1:60) {

for (i in 1:42) {
  
  alpha005 <- (atan(abs(UData005[i,j])/abs(VData005[i,j])))*(180/pi)
  
  if(is.na(UData005[i,j]) || is.na(VData005[i,j])){
    new005[i,j] <- NA
  } else {
    if(UData005[i,j] >= 0 && VData005[i,j] >= 0){
      new005[i,j] <- alpha005+180
    } else { 
      if(UData005[i,j] >= 0 && VData005[i,j] < 0){
        new005[i,j] <- (180-alpha005) +180
      } else {
        if (UData005[i,j] < 0 && VData005[i,j] >= 0){
          new005[i,j] <- (360-alpha005)-180
        } else {
          if(UData005[i,j] < 0 && VData005[i,j] < 0){
            new005[i,] <- (180+alpha005)-180
          } 
        }
      }
    }
  }
}
}
bigben
Beiträge: 2771
Registriert: Mi Okt 12, 2016 9:09 am

Re: Windrichtung berechnen, for loop

Beitrag von bigben »

ExpectoPatronum hat geschrieben: Fr Jul 03, 2020 12:07 pm Mir wird nämlich bei folgendem Code ein Error angegeben: Fehler in new005[i, j] <- alpha005 + 180 : falsche Anzahl von Indizes für Matrix
Wenn sich einer von uns Code ausdenkt, kann er ohne Daten von Dir nicht prüfen, ob sein Code auch Errors produziert. Es wäre daher sehr hilfreich, wenn Du geeignete Musterdaten posten könntest. Im FAQ Forum findest Du einen Threat darüber, wie man das macht. Eine große Hilfe könnten sein

Code: Alles auswählen

dput(UData[1:10,1:60])
dput(VData[1:10,1:60])
LG,
Bernhard
---
Programmiere stets so, dass die Maxime Deines Programmierstils Grundlage allgemeiner Gesetzgebung sein könnte
ExpectoPatronum
Beiträge: 9
Registriert: Fr Jul 03, 2020 10:44 am

Re: Windrichtung berechnen, for loop

Beitrag von ExpectoPatronum »

Das Problem ist, dass ich die Daten leider nicht weitergeben darf ..
bigben
Beiträge: 2771
Registriert: Mi Okt 12, 2016 9:09 am

Re: Windrichtung berechnen, for loop

Beitrag von bigben »

Vielleicht kannst Du die Daten verfälschen, die Reihenfolge in den Zeilen und Spalten permutieren, willkürlich einige Datenpunkte mit Phantasiezahlen überschreiben, bis die Daten wertlos sind? Alternativ nur Phantasiezahlen posten? Müssen ja keine 60 Spalten sein.
---
Programmiere stets so, dass die Maxime Deines Programmierstils Grundlage allgemeiner Gesetzgebung sein könnte
ExpectoPatronum
Beiträge: 9
Registriert: Fr Jul 03, 2020 10:44 am

Re: Windrichtung berechnen, for loop

Beitrag von ExpectoPatronum »

Hab sie jetzt stark verkürzt
Dateianhänge
Vdata.csv
(2.56 KiB) 38-mal heruntergeladen
Udata.csv
(2.37 KiB) 40-mal heruntergeladen
bigben
Beiträge: 2771
Registriert: Mi Okt 12, 2016 9:09 am

Re: Windrichtung berechnen, for loop

Beitrag von bigben »

Dein Code von ganz oben grenzt ans Unübersichtliche. Daher ist es gut, ihn in eine Funktion zu verpacken, die ich hier mal richtung nenne. Kleine Anpassungen im Code umfassen die automatische Bestimmung der Zeilenanzahl, das hinzufügen einer Variable j und ein unlist für das Ergebnis. Die Berechnung sollte unverändert Deine sein:

Code: Alles auswählen

richtung <- function(i, UData005 = UData, VData005 = VData){
  new005 <- list()
  
  for (i in 1:nrow(UData005)) {
    
    alpha005 <- (atan(abs(UData005[i,j])/abs(VData005[i,j])))*(180/pi)
    
    if(is.na(UData005[i,j]) || is.na(VData005[i,j])){
      new005[i] <- NA
    } else {
      if(UData005[i,j] >= 0 && VData005[i,j] >= 0){
        new005[i] <- alpha005+180
      } else { 
        if(UData005[i,j] >= 0 && VData005[i,j] < 0){
          new005[i] <- (180-alpha005) +180
        } else {
          if (UData005[i,j] < 0 && VData005[i,j] >= 0){
            new005[i] <- (360-alpha005)-180
          } else {
            if(UData005[i,j] < 0 && VData005[i,j] < 0){
              new005[i] <- (180+alpha005)-180
            } 
          }
        }
      }
    }
  }
  return(unlist(new005))
}
Jetzt müssen wir die Musterdaten einlesen

Code: Alles auswählen

VData <- read.csv("http://forum.r-statistik.de/download/file.php?id=1045")
UData <- read.csv("http://forum.r-statistik.de/download/file.php?id=1044")
Und das können wir jetzt beispielsweise mit sapply mit den Werten j = 1,2,3,..,16 aufrufen:

Code: Alles auswählen

sapply(1:16, richtung)
LG,
Bernhard
---
Programmiere stets so, dass die Maxime Deines Programmierstils Grundlage allgemeiner Gesetzgebung sein könnte
Athomas
Beiträge: 768
Registriert: Mo Feb 26, 2018 8:19 pm

Re: Windrichtung berechnen, for loop

Beitrag von Athomas »

Ich habe das Ganze unter Beachtung der "sichtbare-Scheifen-Vermeidungs-Philosophie" von R umgesetzt und die "Schleifenverwaltung" durch Verwendung der data.table-Funktionen "melt" bzw. "dcast" (Hin- und Herswitchen zwischen dem "long"- und "wide-" Format) umgangen.

Für die ärgerliche Fallunterscheidung bei der Winkelberechnung gibt es die eingebaute "atan2"-Funktion...

Die Verwendung von "data.table" sollte Dir bei großen Datenmengen eine enorme Beschleunigung bringen...

Code: Alles auswählen

library(data.table)
V <- fread("http://forum.r-statistik.de/download/file.php?id=1045")
U <- fread("http://forum.r-statistik.de/download/file.php?id=1044")
U.lang <- melt(U, id="V1", variable.factor=FALSE, value.name="U")
V.lang <- melt(V, id="V1", variable.factor=FALSE, value.name="V")

intEx <- function(zeichen) as.integer(gsub("[^0-9]", "", zeichen))  # nur Ziffern bleiben erhalten - das geht schöner!

U.lang[  , Ivar:=intEx(variable)]
V.lang[  , Ivar:=intEx(variable)]

Zsamma <- merge(U.lang, V.lang, by=c("V1","Ivar"))
Zsamma[  , Winkel:=atan2(V,U)*(180/pi)]
Erg.DT <- dcast(Zsamma[ , .(V1, Ivar, Winkel)], V1 ~ Ivar, value.var="Winkel")
ExpectoPatronum
Beiträge: 9
Registriert: Fr Jul 03, 2020 10:44 am

Re: Windrichtung berechnen, for loop

Beitrag von ExpectoPatronum »

bigben hat geschrieben: Fr Jul 03, 2020 5:06 pm Dein Code von ganz oben grenzt ans Unübersichtliche. Daher ist es gut, ihn in eine Funktion zu verpacken, die ich hier mal richtung nenne. Kleine Anpassungen im Code umfassen die automatische Bestimmung der Zeilenanzahl, das hinzufügen einer Variable j und ein unlist für das Ergebnis. Die Berechnung sollte unverändert Deine sein:

Code: Alles auswählen

richtung <- function(i, UData005 = UData, VData005 = VData){
  new005 <- list()
  
  for (i in 1:nrow(UData005)) {
    
    alpha005 <- (atan(abs(UData005[i,j])/abs(VData005[i,j])))*(180/pi)
    
    if(is.na(UData005[i,j]) || is.na(VData005[i,j])){
      new005[i] <- NA
    } else {
      if(UData005[i,j] >= 0 && VData005[i,j] >= 0){
        new005[i] <- alpha005+180
      } else { 
        if(UData005[i,j] >= 0 && VData005[i,j] < 0){
          new005[i] <- (180-alpha005) +180
        } else {
          if (UData005[i,j] < 0 && VData005[i,j] >= 0){
            new005[i] <- (360-alpha005)-180
          } else {
            if(UData005[i,j] < 0 && VData005[i,j] < 0){
              new005[i] <- (180+alpha005)-180
            } 
          }
        }
      }
    }
  }
  return(unlist(new005))
}
Jetzt müssen wir die Musterdaten einlesen

Code: Alles auswählen

VData <- read.csv("http://forum.r-statistik.de/download/file.php?id=1045")
UData <- read.csv("http://forum.r-statistik.de/download/file.php?id=1044")
Und das können wir jetzt beispielsweise mit sapply mit den Werten j = 1,2,3,..,16 aufrufen:

Code: Alles auswählen

sapply(1:16, richtung)
LG,
Bernhard
Danke für deine Hilfe!
Allerdings wie bekomme ich da nun eine Tabelle mit den Ergebnissen raus? bei mir passiert da leider gar nichts.. Und fehlt in dem Code nicht noch irgendwo die Festlegung für das j ?
Ich brauch ja nachher wieder eine Tabelle mit gleich vielen Spalten und Zeilen wie die vorherigen Tabellen. Und Eintrag 1 aus U soll mit Eintrag 1 aus V verrechnet werden etc. Geht das so von alleine?
Ich bin grad etwas frustriert, dass bei mir nichts so wirklich funktionieren will...
LG Sarah
Antworten