Seite 1 von 1

Variablen verschachtelt indexieren (autom. Distanzberechnung für mehrere DS)

Verfasst: Di Jan 08, 2019 9:49 am
von sblatt
Hallo zusammen,

zu Trainingszwecken habe ich 5 Einträge der "Species-Spalte" des Iris DS gelöscht und möchte diese nun über die Ähnlichkeit der restlichen DS mit Hilfe des Minimums des Euklid'schen Abstands prognostizieren. Für eine Zeile klappt das noch (wenn auch etwas holprig):

Code: Alles auswählen

#Löschung von "Species" in der 1. Zeile von Iris:
zu.bestimmender.Fall <- iris[1,-5]
#Funktion dist() funktioniert nicht: nur die ersten 6 Zeilen werden bestimmt - warum?

#Daher Bestimmung der Distanz (Euklid) zw. Z1 und allen anderen DS
#Als Zielklasse des zu bestimmenden 1. DS wird die Ausprägung der ZK des DS mit 
#der geringsten Distanz übernommen
#dist_1 <- 0
#i <- 2
for (i in 2:150){
  dist_1[i] <- sqrt((iris[i,1]-iris[1,1])^2+(iris[i,2]-iris[1,2])^2+(iris[i,3]-iris[1,3])^2+(iris[i,4]-iris[1,4])^2)
}

Zielklasse.gesucht <- iris[which(dist_1[-1]==min(dist_1[-1]))+1,5]  
#+1 ist Korrektur für die falsch zählende Schleife, -1 eliminiert den 1. DS (0), damit das echte Min gefunden wird

#Das war ein Bsp. für einen zu bestimmenden Datensatz - gibt es mehrere DS, bei 
#denen das Attribut fehlt, muss diese Prozedur über eine weitere Schleife auf alle
#betroffenen DS ausgedehnt werden - wie? -> die auf Z1 zeigende 1 muss ebenfalls
#indexiert werden mit den Nummern aller Zeilen, bei denen ebenfalls Attribut leer

#Iris-Datensatz wurde modifiziert: 5 Einträge bei Species wurden gelöscht mit der
#Zielsetzung, diese alle automatisiert über eine verschachtelte Schleife über
#Dist_Euklid zu ermitteln

# 1. Ermittlung der betroffenen DS
iris.fehlend <- subset(iris.5fehlend, iris.5fehlend$species=='')
iris.gefuellt <- subset(iris.5fehlend, iris.5fehlend$species!='')

for (n in 1:nrow(iris.fehlend)) {
  for (i in 1:nrow(iris.gefuellt)) {
dist[n, i] <- sqrt((iris.gefuellt[i,1]-iris.fehlend[n,1])^2+(iris.gefuellt[i,2]-iris.fehlend[n,2])^2+(iris.gefuellt[i,3]-iris.fehlend[n,3])^2+(iris.gefuellt[i,4]-iris.fehlend[n,4])^2)

}
} 
Dies führt zu folgender Fehlermeldung:
Error in dist[n, i] <- sqrt((iris.gefuellt[i, 1] - iris.fehlend[n, 1])^2 + :
object of type 'closure' is not subsettable


Mein Ziel ist eigentlich, dass mir mein Code am Ende das Attribut "Species" für die 5 Zeilen, wo dieser Eintrag fehlt, automatisch ausspuckt, indem eine Schleife 5 mal (für jede Zeile, wo Attribut fehlt) den ähnlichsten DS ermittelt, daraus das "Species" übernimmt und diesen Wert dann in die Zelle reinschreibt, wo er fehlt. Das mit der mehrfachen Indexierung scheint aber zumindet so nicht zu funktionieren. Wie kann ich denn eine Variable so dynamisieren, dass ich den Code nicht für jede einzelne Fehlerzeile schreiben muss?


Vielen Dank schon mal

Re: Variablen verschachtelt indexieren (autom. Distanzberechnung für mehrere DS)

Verfasst: Di Jan 08, 2019 10:57 am
von bigben
R sieht diesen Zeilenanfang:

Code: Alles auswählen

dist[n, i] <-
und überlegt, was Du mit 'dist' meinen könntest. Eine Variable mit Namen 'dist' existiert nicht, wohl aber eine Funktion mit Namen 'dist'. Als nächstes sieht R, dass Du mit der eckigen Klammer ein subset von dist auswählen möchtest. Funktionen aber aber keine subsets, deshalb der Fehler, den Du auch so reproduzieren kannst:

Code: Alles auswählen

dist[1]
#wahlweise auch
plot[1]
Die Fehlermeldung ist also ein berechtigter Syntax error.

LG,
Bernhard

Re: Variablen verschachtelt indexieren (autom. Distanzberechnung für mehrere DS)

Verfasst: Di Jan 08, 2019 10:58 am
von jogo
Hallo sblatt,

bei mir sieht das so aus:

Code: Alles auswählen

iris1 <- iris[1, ]
i1 <- unlist(iris1[-5])

irisRest <- iris[-1,]
M <- as.matrix(irisRest[-5])

rowSums((sweep(M, 2, i1))^2) ## das ist der Vektor dist
min(rowSums((sweep(M, 2, i1))^2))
w <- which.min(rowSums((sweep(M, 2, i1))^2))
sum((unlist(irisRest[w, -5]) - i1)^2) ## Kontrolle

irisRest$Species[w] ## welche Spezies?
iris[1, 5] ## Vergleich
Oder man verwendet die Funktion dist()

Code: Alles auswählen

d <- as.matrix(dist(iris[-5]))[1,]
d
Für fünf verschiedene Zeilen des Datensatzes sieht die Vorhersage bei mir so aus:

Code: Alles auswählen

set.seed(42)
s <- sample(1:150, 5)
irisS <- iris[s, ]
irisRest <- iris[-s, ]
M <- as.matrix(irisRest[-5])

findeSpez <- function(i1) {
  w <- which.min(rowSums((sweep(M, 2, i1))^2))
  irisRest$Species[w] ## welche Spezies?
}
data.frame(predSpez=apply(irisS[-5], 1, findeSpez), echt=irisS$Species)
Gruß, Jörg

Re: Variablen verschachtelt indexieren (autom. Distanzberechnung für mehrere DS)

Verfasst: Di Jan 08, 2019 11:40 am
von sblatt
Vielen Dank, schau ich mir in Ruhe an, bin leider noch immer irgendwie Anfänger.

Re: Variablen verschachtelt indexieren (autom. Distanzberechnung für mehrere DS)

Verfasst: Di Jan 08, 2019 2:18 pm
von Athomas
bin leider noch immer irgendwie Anfänger
Kein Problem, das waren wir alle mal :D !

Aber wenn Du R über einen längeren Zeitraum und/oder intensiver nutzen möchtest, solltest Du an diesem Zustand etwas ändern!
Das ist für alle Beteiligten besser...

Re: Variablen verschachtelt indexieren (autom. Distanzberechnung für mehrere DS)

Verfasst: Di Jan 08, 2019 11:56 pm
von EDi

Code: Alles auswählen

object of type 'closure' is not subsettable
Die Fehlermeldung ist also ein berechtigter Syntax error.
Und hier und hier die Erklärung warum Funktionen "closures" sind (und in R so bezeichnet werden).

Code: Alles auswählen

> typeof(dist)
[1] "closure"
Siehe auch ?typeof. Als Fehlemeldung wäre es vermutlich besser "function", statt "closure" zu nehmen....

Re: Variablen verschachtelt indexieren (autom. Distanzberechnung für mehrere DS)

Verfasst: Di Jan 15, 2019 11:05 pm
von jogo
Hallo Sven,

sblatt schrieb:
Hallo Jörg,

vielen Dank für deine Hilfe. Ich hätte nicht gedacht, dass man dies so elegant lösen kann. Ich zerbreche mir allerdings schon seit Tagen den Kopf, was genau in dieser Zeile passiert:

w <- which.min(rowSums((sweep(M, 2, i1))^2))

Was ich verstehe ist, dass die Zeile gesucht wird, bei der die Zeilensumme ihr Minimum hat. Bei sweep verstehe ich noch, dass eine Funktion i1 spaltenweise auf die Matrix M angewendet wird und dies dann noch quadriert wird. Was ist denn aber die Funktion i1? Ist das eine definierte statistische Funktion für die Abstandermittlung? Ich kriege die Formel der Abstandermittlung nach Euklid einfach nicht überein mit deiner Formel - oder liegt dem ein vereinfachender mathematischer Schluss zugrunde?

Wäre dir dankbar, wenn du hier noch etwas Licht ins Dunkle bringen könntest.
Das Objekt i1 habe ich doch in meinem Code definiert:

Code: Alles auswählen

iris1 <- iris[1, ]
i1 <- unlist(iris1[-5])
Es ist die erste Zeile aus dem Dataframe iris ohne "Species".
Der Dokumentation von sleep() ist zu entnehmen, dass das vierte Argument die Funktion ist - und wenn die Funktion nicht angegeben wird, ist es die Subtraktion. Ich hätte beim sleep() also auch schreiben können:

Code: Alles auswählen

sweep(x=M, MARGIN=2, STATS=i1, FUN = "-")
Bitte schaue Dir die Dokumentation von sweep() an:

Code: Alles auswählen

help("sweep")
und auch die Beispiele:

Code: Alles auswählen

example("sweep")
Was insgesamt berechnet wird, ist nicht ganz die euklidische Norm, denn dafür fehlt die Quadratwurzel (über der Summe der Quadrate). Für die gesuchte Minimumstelle ist das aber unerheblich.

Bitte lies im Bereich FAQ den Text viewtopic.php?f=20&t=45 und halte Dich zukünftig daran!

Gruß, Jörg