2017-03-26 1 views
2

Ich verwende die folgende Methode von Daniel Weidele, um eine Brainerd-Robinson-Ähnlichkeit für eine Reihe von Daten zu berechnen (Code unten). Meine Zeilen repräsentieren Orte und meine Spalten stellen das Alter von Personen dar, die an jedem Ort gefunden wurden. Ich verwende Ähnlichkeit, um zu messen, welche Orte ähnliche demographische Zusammensetzungen haben, und dann verwende ich die Ausgabe in einer Netzwerkanalyse.Ohne 0 von Brainerd-Robinson-Ähnlichkeit

Mein Problem ist, dass viele meiner Orte haben '0' Menschen in bestimmten Altersgruppen, und so zeigt der Ähnlichkeitsindex starke Verbindungen zwischen diesen Orten. Ich würde gerne zwei Iterationen des Modells ausführen, sowohl i) wo die '0's berücksichtigt werden und ii) wo' 0 'ignoriert werden, d. H., Ich gebe einfach Indizes zurück, die mit positiven Daten erzeugt wurden.

Ich habe verschiedene Methoden ausprobiert, um "0" aus der Analyse auszuschließen, und nichts hat bisher funktioniert. Irgendwelche Vorschläge dafür? Vielen Dank.

# function to load the observations 
 
load = function() { 
 
    p <- read.csv("observations.csv") 
 
    rownames(p) <- p[,1] 
 
    p <- p[,c(2:6)] 
 
    return(p) 
 
} 
 

 
# function to compute the normalized Brainerd-Robinson similarity for observations x 
 
BR <- function(x) 
 
{ 
 
    rd <- dim(x)[1] 
 
    results <- matrix(0,rd,rd) 
 
    for (s1 in 1:rd) { 
 
    for (s2 in 1:rd) { 
 
     results[s1,s2] <- 1 - (sum(abs(x[s1, ]/sum(x[s1,]) - x[s2, ]/sum(x[s2,]))))/2 
 
    } 
 
    } 
 
    rownames(results) <- rownames(x) 
 
    colnames(results) <- rownames(x) 
 
    return(results) 
 
} 
 

 
# load observations, compute Brainerd-Robinson similarity and write results to file 
 
write.csv(BR(load()), "br.csv")

+0

Wäre es sinnvoll für Ihre Daten, die Eingabe in allen Altersgruppen an Orten von 0 eine durchschnittliche machen? –

+0

Ich hätte dann das selbe Problem, oder? Wenn alle 0 durch dasselbe n ersetzt werden, werden diese Werte immer noch als 100% 'ähnlich' markiert? – michael

+0

Wenn ich alle meine '0' durch NA ersetzen würde, wäre es ein guter Weg, sie von der Analyse auszuschließen? – michael

Antwort

0

Warum direkt an den Autor nicht fragen? :)

Wenn Sie an der Linie sehen

results[s1,s2] <- 1 - (sum(abs(x[s1, ]/sum(x[s1,]) - x[s2, ]/sum(x[s2,]))))/2 

dies meist, wo geschieht die Magie. Lassen Sie mich erläutern, was hier vor sich geht, nur auf der rechten Seite des Zuweisungsoperation suchen <-:

1 - (sum(abs(x[s1, ]/sum(x[s1,]) - x[s2, ]/sum(x[s2,]))))/2 

uns

  • der Vektor x[s1,] die Obvserations von Standort 1 (OOS1 nennen lassen),
  • die Nummer (oder Skalar) sum(x[s1,]), die dann ist sum(OOS1) die Summe der Website 1 (SOS1),
  • und der Vektor x[s1,]/sum(x[s1,]) die Normalized Beobachtungen von Standort 1 (NOS1)

Wir können dann unseren rechten Teil der Zuordnung neu schreiben zu:

1 - (sum(abs(OOS1/SOS1 - OOS2/SOS2)))/2 

oder

1 - (sum(abs(NOS1 - NOS2)))/2 

Der wichtige Teil ist, dass NOS1 und NOS2 immer noch Vektoren sind, die die Anzahl der beobachteten Werte pro Kategorie enthalten, gerade normalisiert auf den Anteil an der Stelle.

Jetzt der entscheidende Teil für Ihre Frage: abs(NOS1 - NOS2).

NOS1 - NOS2 

subtrahiert einfach einen Vektor vom anderen.Dies ist, wo Sie Ihre Änderung machen, um für 0 Werte nicht zu berücksichtigen:

differenceIgnoreZeroes <- function(u, v) 
{ 
    # input vectors u and v should have equal length for this to work 
    result <- vector() 
    for (i in 1:length(u)) { 
    if(u[i] == 0 || v[i] == 0) next # SKIP IF EITHER VALUE IS 0 
    result[i] <- u[i] - v[i]  
    } 
    return(result) 
} 

diese Funktion definiert Nachdem wir schreiben also differenceIgnoreZeroes(NOS1, NOS2) statt NOS1-NOS2.

Weiter geht es neben den absoluten Wert unter nach wie vor:

abs(differenceIgnoreZeroes(NOS1, NOS2)) 

Wie die resultierende Vektorwerte ‚NA‘ enthält jetzt, wenn sie über den Vektor Summieren wir nicht erklären diese NA s vorsichtig sein müssen, sonst würde die ganze Summe auch NA werden. Daher einen Parameter na.rm bis T (rue):

sum(abs(differenceIgnoreZeroes(NOS1,NOS2)), na.rm = T) 

Somit unserer gesamten rechten Zuordnung sieht wie folgt aus:

1 - (sum(abs(differenceIgnoreZeroes(OOS1/SOS1, OOS2/SOS2)), na.rm = T))/2 

die zu

expandiert weiter
1 - (sum(abs(differenceIgnoreZeroes(x[s1, ]/sum(x[s1,]), 
x[s2, ]/sum(x[s2,]))), na.rm = T))/2 

Ich hoffe, das hilft!

Cheers,

Daniel Weidele