Seite 1 von 1

NA ignorieren

Verfasst: So Nov 24, 2019 12:28 am
von Dafmen
Guten Abend,

es hat sich ergeben das einige Werte des Datensatzes noch vor dem einlesen in R gelöscht werden mussten (ein Wert im angehängten Beispieldatensatz fehlt).
Mein Ziel ist, dass die fehlenden Werte nicht weiter beachtet werden und sich, in diesem zweifaktoriellen Versuch mit vier Wiederholungen, einfach die Stichprobe verkleinert (auf drei Wiederholungen).

Ich habe mich jetzt durch alle NA-Funktionen gekämpft die ich gefunden habe.
Prinzipiell wäre "na.rm=TRUE" die Formel die ich suche, jedoch funktioniert sie nicht.

Code: Alles auswählen

LAI2_Block1 <- ave(dataset$LAI2,dataset$B_1,na.rm=FALSE,FUN=mean)
LAI2_Var <- ave(dataset$LAI2, dataset$F_1, na.rm=TRUE,FUN=mean)
LAI2_B1 <- dataset$LAI2 - LAI2_Block1 + LAI2_Var
LAI2_Block2 <- ave(dataset$LAI2,dataset$B_2,na.rm=TRUE,FUN=mean)
LAI2_B2 <- dataset$LAI2 - LAI2_Block2 + LAI2_Var
LAI2_korr <- (LAI1_B1+LAI2_B2+dataset$LAI1)/3
LAI2_korr

Code: Alles auswählen

###output
[1]       NA 1.182313       NA       NA 1.430896       NA       NA       NA 1.401979
[10] 1.633312 1.444396 1.688063       NA       NA       NA       NA       NA       NA
[19]       NA 1.304396 1.650896 1.554229       NA       NA       NA 1.635229       NA
[28] 1.478313       NA 1.413479       NA       NA
Die Formel vergrößert die Anzahl der NAs, statt die entsprechende Stichprobe zu verkleinern. Könnt ihr mir bitte meinen Fehler aufzeigen bzw. mich berichtigen?

Danke und Gruß,
Sebastian

Re: NA ignorieren

Verfasst: So Nov 24, 2019 11:21 am
von Hufeisen
Ich kann Dir leider nicht ganz folgen. Dein Code-Beispiel ist nicht vollständig und stimmt nicht mit der angehängten Datei Mappe1.csv überein. Es gibt zum Beispiel keine mit LAI2 überschriebene Spalte. Wie liest du die Daten ein? Ansonsten könnte es schon Abhilfe schaffen, alle Argumente na.rm auf TRUE zu setzen. In der ersten Zeile hast du eines als FALSE deklariert.

Re: NA ignorieren

Verfasst: So Nov 24, 2019 12:29 pm
von Dafmen
Sorry, ich musste meinen Datensatz etwas abändern, deswegen stimmten die Spaltennamen nicht.

So sollte es passen

Code: Alles auswählen

Messung2_Block1 <- ave(dataset$Messung2,dataset$B_1,na.rm=TRUE,FUN=mean)
Messung2_Var <- ave(dataset$Messung2, dataset$F_1, na.rm=TRUE,FUN=mean)
Messung2_B1 <- dataset$Messung2 - Messung2_Block1 + Messung2_Var

Messung2_Block2 <- ave(dataset$Messung2,dataset$B_2,na.rm=TRUE,FUN=mean)
Messung2_B2 <- dataset$Messung2 - Messung2_Block2 + Messung2_Var

Messung2_korr <- (Messung2_B1+Messung2_B2+dataset$Messung2)/3
Messung2_korr
Als Output erhalte ich dann

Code: Alles auswählen

####Output
[1]       NA 1.952458       NA       NA 1.868375       NA       NA
 [8]       NA 2.164542 1.938542 2.371625 1.802625       NA       NA
[15]       NA       NA       NA       NA       NA       NA       NA
[22]       NA       NA       NA       NA 1.694375       NA 1.883458
[29]       NA 1.979292       NA       NA
Ehrlicherweise frage ich mich, weshalb die NAs nicht einfach, gemäß des Befehls "na.rm=TRUE" ignoriert werden.

Re: NA ignorieren

Verfasst: So Nov 24, 2019 1:04 pm
von student
Wenn es möglich ist, empfehle ich immer, die NA's aus dem Datensatz zu entfernen! Sie hier!

Re: NA ignorieren

Verfasst: So Nov 24, 2019 1:19 pm
von Hufeisen
Ich vermute, dass das Argument na.rm = TRUE nicht an die Funktion mean() weitergegeben wird, denn in der Hilfe sind dafür keine Platzhalter vorgesehen.
Usage

ave(x, ..., FUN = mean)
Also muss man NA entweder vorher entfernen oder bei der Rechnung ausnehmen. Letzteres habe ich gemacht. Du hast mir nicht gezeigt, wie du die Daten einliest. Also habe ich es "einfach so" gemacht. Die meisten Faktoren werden deshalb nicht als solche erkannt, aber es geht trotzdem.

Code: Alles auswählen

# Im Arbeitsverzeichnis
dataset <- read.csv2(file = "Mappe1.csv")
str(dataset) # Faktoren nicht als solche deklariert, geht aber trotzdem

# Testoutput mit Deiner ersten Codezeile 
  # Output mit NA
  ave(dataset$Messung2, dataset$B_1, na.rm = TRUE, FUN = mean)
  # [1] 2.267125 2.267125 2.267125 2.267125 2.267125 2.267125 2.267125 2.267125 2.587875 2.587875 2.587875 2.587875 2.587875 2.587875 2.587875 2.587875
  # [17]       NA       NA       NA       NA       NA       NA       NA       NA 2.531375 2.531375 2.531375 2.531375 2.531375 2.531375 2.531375 2.531375

# NA spaltenweise suchen
meine_funktion <- function(x) {sum(is.na(x))}
apply(dataset, 2, FUN = meine_funktion) # Messung2 enthält ein NA
  
# NA zeilenweise suchen und die Zeilen abspeichern
Zeilen_mit_NA <- apply(dataset, 1, FUN = meine_funktion)

  # Testoutput mit Deiner ersten Codezeile ohne Zeilen mit NA
  ave(dataset$Messung2[!Zeilen_mit_NA], dataset$B_1[!Zeilen_mit_NA], FUN = mean)
  ave(dataset$Messung2[!Zeilen_mit_NA], dataset$B_1[!Zeilen_mit_NA], FUN = mean)
  # [1] 2.267125 2.267125 2.267125 2.267125 2.267125 2.267125 2.267125 2.267125 2.587875 2.587875 2.587875 2.587875 2.587875 2.587875 2.587875 2.587875
  # [17] 2.450143 2.450143 2.450143 2.450143 2.450143 2.450143 2.450143 2.531375 2.531375 2.531375 2.531375 2.531375 2.531375 2.531375 2.531375

# Der ganze Code
  Messung2_Block1 <- ave(dataset$Messung2[!Zeilen_mit_NA], dataset$B_1[!Zeilen_mit_NA], FUN = mean)
  Messung2_Var <- ave(dataset$Messung2[!Zeilen_mit_NA], dataset$F_1[!Zeilen_mit_NA], FUN = mean)
  Messung2_B1 <- dataset$Messung2[!Zeilen_mit_NA] - Messung2_Block1 + Messung2_Var
  Messung2_Block2 <- ave(dataset$Messung2[!Zeilen_mit_NA], dataset$B_2[!Zeilen_mit_NA] , FUN = mean)
  Messung2_B2 <- dataset$Messung2[!Zeilen_mit_NA] - Messung2_Block2 + Messung2_Var
  Messung2_korr <- (Messung2_B1 + Messung2_B2 + dataset$Messung2[!Zeilen_mit_NA]) / 3
  Messung2_korr
  
  # Output  
  #[1] 2.722878 1.952458 3.251961 2.313961 1.868375 2.954794 1.907821 1.732821 2.164542 1.938542 2.371625 1.802625 3.204878 2.727878 3.125324 3.080324
  #[17] 3.356872 3.018872 2.396955 1.722536 1.852369 2.622369 2.036815 3.439794 1.694375 3.263878 1.883458 2.839711 1.979292 1.961738 3.052158

Re: NA ignorieren

Verfasst: So Nov 24, 2019 4:37 pm
von Dafmen
Danke für die Antwort,

leider hat das Output ledigleich einen Umfang von 31 Werten, statt 32. Ich brauche zwingend 32 in unveränderter Reihenfolge.
Zu jeder Faktorkombination (z.B. "Pauletta 30") gibt es vier Messwerte.
Wenn, bedingt durch den fehlenden Wert, lediglich drei Messwerte bei der Berechnung einer Faktorkombination verwendet werden können, spielt das keine Rolle.

Vielleicht gibt es auch eine andere Funktion als "ave", mit der man das gleiche machen und zusätzlich ein na.rm=TRUE einbinden kann. Leider fehlt mir dafür die Kreativität sowie die Erfahrung mit R

mit folgender Funktion habe ich die Faktoren aus Spalte "F_2", welche als ganze Zahlen erkannt werden, in Faktoren gewandelt. Sonst lese ich die Daten genau so ein, wie du es auch getan hast.

Code: Alles auswählen

dataset$F_2 <- as.factor(dataset$F_2)

Re: NA ignorieren

Verfasst: So Nov 24, 2019 5:41 pm
von Hufeisen
Dafmen hat geschrieben: So Nov 24, 2019 4:37 pmleider hat das Output ledigleich einen Umfang von 31 Werten, statt 32. Ich brauche zwingend 32 in unveränderter Reihenfolge.
Zu jeder Faktorkombination (z.B. "Pauletta 30") gibt es vier Messwerte.
Wenn, bedingt durch den fehlenden Wert, lediglich drei Messwerte bei der Berechnung einer Faktorkombination verwendet werden können, spielt das keine Rolle.
Ich muss gestehen, dass ich Dein Problem nur neben meiner eigentlichen Arbeit her gelöst habe, ohne genau zu durchdringen, was Du da eigentlich machst. Deshalb fällt es mir nun schwer, eine garantiert richtige Lösung vorzuschlagen. Wenn es nur um die reine Länge des Vektors geht, könnte man einfach ein Element mit dem Wert NA (???) einfügen. Aber das könnte auch völliger Käse sein.

Code: Alles auswählen

Messung2_korr_neu <- c(Messung2_korr[1:22], NA, Messung2_korr[23:31])

  # Output
  Messung2_korr_neu
  #[1] 2.722878 1.952458 3.251961 2.313961 1.868375 2.954794 1.907821 1.732821 2.164542 1.938542 2.371625 1.802625 3.204878 2.727878 3.125324 3.080324
  #[17] 3.356872 3.018872 2.396955 1.722536 1.852369 2.622369       NA 2.036815 3.439794 1.694375 3.263878 1.883458 2.839711 1.979292 1.961738 3.052158

Re: NA ignorieren

Verfasst: So Nov 24, 2019 6:07 pm
von Dafmen
Ich muss gestehen, dass ich Dein Problem nur neben meiner eigentlichen Arbeit her gelöst habe, ohne genau zu durchdringen, was Du da eigentlich machst. Deshalb fällt es mir nun schwer, eine garantiert richtige Lösung vorzuschlagen. Wenn es nur um die reine Länge des Vektors geht, könnte man einfach ein Element mit dem Wert NA (???) einfügen. Aber das könnte auch völliger Käse sein.

Ich bin dir auch dankbar das du dich meines Problems annimmst. Leider ist das keine so gute Lösung, da die vier Einzelwerte nach der Berechnung zu einem Mittelwert zusammengeführt werden, wo dann das nächste Problem auftreten wird.

Tut mir leid, wenn ich mein Problem nicht so gut beschrieben habe.
Aber es geht darum, dass den Messwertn von z.B. "Pauletta:30" oder "BTS:30" jeweils vier Rohdaten zugrunde liegen (aufgrund von vier Varianten).
Einige Rohdaten wurden als Ausreißer erkannt und gelöscht.

Demnach liegen jedem Faktor vier Messwerte zugrunde, wobei ich möchte, dass, wenn ein NA erkannt wird, für diesen Faktor lediglich drei Messwerte genutzt werden.
Das NA soll lediglich ignoriert werden (praktisch als wäre die NA-Zelle garnicht da), ohne, dass der Datensatz gekürzt wird oder irgendein anderer Wert beeinflusst wird.

Re: NA ignorieren

Verfasst: Mo Nov 25, 2019 4:30 pm
von Hufeisen
Mhh, ich glaube ich verstehe schon, was du erreichen willst, aber ich komme nicht drauf, wie man das lösen könnte. Man könnte in den Zwischenschritten einfach den fehlenden Wert ergänzen. Aber spätestens in dem Schritt

Code: Alles auswählen

Messung2_B1 <- dataset$Messung2 - Messung2_Block1 + Messung2_Var
... werden die Zwischenschritte Block1 und Var nochmals mit den ursprünglichen Messwerten addiert bzw. subtrahiert. Was will man da einsetzen, wenn in Zeile 23 kein Wert vorhanden ist?

Re: NA ignorieren

Verfasst: Mo Nov 25, 2019 6:12 pm
von Dafmen
Ich habe jetzt nochmal nachgeschaut. In "tapply" kann man "na.rm=TRUE" zielführend eingeben. Jedoch ist die Datenausgabe eine gänzlich andere.

Code: Alles auswählen

###Ausgangscode
ave(dataset$Messung2,dataset$B_1,FUN=mean)

###mit tapply
 tapply(dataset$Messung2,dataset$B_1,mean,na.rm=TRUE)
Tapply gibt praktisch für jeden Block (1,2,3,4) den entsprechenden Mittelwert raus, was prinzipiell richtig ist, jedoch müsste ich dann in der Lage sein, die einzelnen Werte direkt ansprechen zu können um sie weiterverwenden zu können. Ist das möglich?
Form des tapply-Output

Code: Alles auswählen

###Beispielhafter Output für tapply für den Beispieldatensatz
1      2     3       4
a      b     c       d
Ist es dann möglich, z.B. nur "1" anzusprechen und mit dem Wert "a" weiterzurechnen?




---------------------------
Edit:

Ich glaube, dass ich es jetzt gelöst habe. Jetzt muss der Output nur noch in eine Tabelle übertragbar sein und in einer Gafik darstellbar sein.

Code: Alles auswählen

tMessung2_Block1<-tapply(dataset$Messung2,dataset$B_1,mean,na.rm=TRUE)
tMessung2_Var <- tapply(dataset$Messung2, dataset$F_1:dataset$F_2,mean,na.rm=TRUE)

tMessung2_B1 <- dataset$Messung2 - tMessung2_Block1[dataset$Messung2] + tMessung2_Var[dataset$F_1:dataset$F_2]
tMessung2_Block2 <-tapply(dataset$Messung2,dataset$B_2,mean,na.rm=TRUE)
tMessung2_B2<-dataset$Messung2 - tMessung2_Block2[dataset$Messung2] + tMessung2_Var[dataset$F_1:dataset$F_2]
tMessung2_korr<-(tMessung2_B1+tMessung2_B2+dataset$Messung2)/3
tMessung2_korr
Als Output erhalte ich:

Code: Alles auswählen

2        2        2        1        2        2        2        1        2 
2.546500 2.098167 3.357889 2.096500 1.802333 3.040333 1.818167 1.554667 2.228167 
       2        2        1        3        2        2        2        3        2 
1.994333 2.544167 1.697667 3.463633 2.655667 3.286333 2.964500 3.499077 2.915667 
       2        1        2        2     <NA>        2        3        1        3 
2.201500 1.687000 1.739833 2.814167       NA 2.000333 3.694633 1.650667 3.353077 
       2        2        2        2        2 
1.840333 2.736500 2.009167 2.149167 2.929667
Allerdings ist nun die Frage, wofur die Zahlen über den Werten stehen (1,2,3).