2016-04-05 9 views
0

Ich habe 2 Matrizen, ich möchte sie vergleichen (row.name weise), um den Unterschied zu finden.Vergleichen Sie Matrizen, um die Unterschiede zu finden

> head(N1) 
       Total_Degree Transitivity Betweenness Closeness_All 
2410016O06RIK   1   NaN  0.00000 0.0003124024 
AGO1      4 0.1666667 37.00000 0.0003133814 
APEX1     4 0.6666667  4.00000 0.0003144654 
ATR      4 0.1666667 19.50000 0.0003128911 
CASP3     24 0.0000000 806.00000 0.0002980626 
CCND2     4 0.3333333 97.33333 0.0003132832 

head(N2) 
       Total_Degree Transitivity Betweenness Closeness_All 
2410016O06RIK   1   NaN   0.0 2.279982e-04 
ADI1      1   NaN   0.0 1.728877e-05 
AGO1      3 0.0000000  40.0 2.284670e-04 
AIRN      1   NaN   0.0 1.721733e-05 
APEX1     3 0.6666667   2.0 2.288330e-04 
ATR      3 0.3333333  19.5 2.281542e-04 

Viele der rows.name in N1 Sie in N2 existieren, möchte ich sie vergleichen und den Unterschied in einer neuen Matrix zu schreiben. Diejenigen, die für N1 oder N2 einzigartig sind, sollten erwähnt werden, dass sie entweder zu N1 oder N2 gehören.

Ich bin mir nicht sicher, welches ist das beste Kriterium, um den Unterschied zu berechnen, was ich mir vorstellen kann, ist eine einfache Addition aller Werte einer Zeile in N1 und subtrahiere diesen Wert vom additiven Wert der entsprechenden Zeile in N2.

Zum Beispiel ausgegeben werden soll:

> head(Compared) 
         Comparison Unique 
    2410016O06RIK  0.0002  Common 
    AGO1     -1.83  Common 
    APEX1     2.24  Common 
    ATR     0.0034  Common 
    CASP3    830.00029 N1 
    ADI1    1.0007288 N2 

hier für row.name = 2410016O06RIK, alle Werte von N1 und N2 wurden hinzugefügt und dann N1-N2 wurde in Comparison Spalte geschrieben, da diese Zeile in beiden Matrizen üblich war so common wurde in Unique Spalte geschrieben.

+0

Konnten Sie Code zur Verfügung stellen, um die Daten zu reproduzieren? Für die Eindeutigkeit würde ich mit inneren und linken/rechten Joins nach row.name gehen, dann einfach drei resultierende data.frames, und für den Unterschied könnte vielleicht 'all.equal()' den Job machen? Sie müssen angeben, was Sie mit einer "Differenz" meinen. –

+0

@ M.D Ich lese die Textdateien hier, ich weiß nicht, wie ich Ihnen die Daten liefern kann. Aus Differenz meine ich "lasst uns diese Zeile betrachten. Namen sind unterschiedliche Personen und wir haben ihr Einkommen aus verschiedenen Quellen in verschiedenen Spalten. Wir berechnen ihr Gesamteinkommen (alle Werte einer Zeile addierend) in 2 Zeitpunkten (N1 und N2) und wir möchte die Person herausfinden, deren Einkommen sich über diese Zeitpunkte drastisch verändert hat (durch Subtraktion von N1 - N2) ". – user3253470

+0

Das ist ein Entwurf der Lösung mit dem Paket data.table, wenn Sie nicht damit vertraut sind, werde ich versuchen, es ohne es zu schreiben: (Hier war der Code, aber ich werde es als eine Lösung für die Lesbarkeit veröffentlichen). –

Antwort

4

Eine Art und Weise in der Basis R zu gehen, mit rowSums und merge:

Wenn N1 und N2 sind data.frames:

# compute the row sums and merge N1 and N2 
N1$rs <- rowSums(N1, na.rm=TRUE) 
N2$rs <- rowSums(N2, na.rm=TRUE) 
comp <- merge(N1[, "rs", drop=FALSE], N2[, "rs", drop=FALSE], by="row.names", all=TRUE) 

# then compare the row sums and the variable "locations" 
comp$Unique <- with(comp, c("N1", "N2", "common")[(!is.na(rs.x)) + 2*(!is.na(rs.y))]) 
comp$Comparison <- with(comp, rs.x-rs.y) 

# keep only the variable you need: 
comp <- comp[, c(1, 5, 4)] 

Wenn N1 und N2 Matrizen sind:

# compute the row sums and merge N1 and N2 
rs1 <- rowSums(N1, na.rm=TRUE) 
rs2 <- rowSums(N2, na.rm=TRUE) 
comp <- merge(N1, N2, by="row.names", all=TRUE) 

# then compare the row sums and the variable "locations" 
comp$Unique <- with(comp, c("N1", "N2", "common")[as.numeric(!is.na(Total_Degree.x)) + 2*as.numeric(!is.na(Total_Degree.y))]) 
comp$Comparison <- with(merge(as.data.frame(rs1), as.data.frame(rs2), all=TRUE, by="row.names"), rs1-rs2) 

# keep only the variable you need: 
comp <- comp[, c("Row.names", "Comparison", "Unique")] 

Ausgang beiden Methoden:

comp 
#  Row.names Comparison Unique 
#1 2410016O06RIK 0.0000844042 common 
#2   ADI1   NA  N2 
#3   AGO1 -1.8332483856 common 
#4   AIRN   NA  N2 
#5   APEX1 3.0000856324 common 
#6   ATR 0.8334181369 common 
#7   CASP3   NA  N1 
#8   CCND2   NA  N1 
+0

'comp <- merge (N1 [," rs ", drop = FALSE], N2 [," rs ", drop = FALSE], durch =" row.names ", all = TRUE)' Dieser Befehl ergibt: * * Fehler in N1 [, "rs", drop = FALSE]: falsche Anzahl der Dimensionen **. Kannst du mir sagen, wie ich es lösen kann? Danke für die Antwort. – user3253470

+0

Danke für die Antwort. Denken Sie, dass dies der richtige Weg ist, die Matrizen/Datenrahmen zu vergleichen, um die Unterschiede zu erhalten, oder gibt es andere Methoden? Zweitens, können Sie mir sagen, wie ich die Daten für zukünftige Fragen bereitstellen kann? Danke in der Tat. – user3253470

+0

@ user3253470, einfachste Frage: Sie können entweder ein kleines reproduzierbares Beispiel von Dummy-Daten erstellen oder 'dput' auf einen Teil Ihrer Daten verwenden, um uns die Struktur zu geben. Für Ihre andere Frage, ich denke, es hängt davon ab, welche Art von Informationen Sie suchen. Ist der Unterschied von rowSums sinnvoll? Brauchen Sie einen variablen Unterschied? etwas anderes ? Ich würde sagen, es hängt davon ab, was Sie wirklich brauchen ... – Cath

2

, dass ein Teil der Lösung ist, in res Sie ein data.table haben mit für den Unterschied Teil zu arbeiten:

require(data.table) 
require(dplyr) 

set.seed(2016) 
dt1 <- data.table(V1 = c("a", "b", "c", "d"), V2 = rnorm(4)) 
dt2 <- data.table(V1 = c("c", "d", "e", "f"), V2 = rnorm(4)) 

# common <- merge(dt1, dt2, by = "V1")[, Unique := "Common"] 
# unique1 <- dt1[V1 %nin% dt2[, V1], ][, Unique := "N1"] 
# unique2 <- dt2[V1 %nin% dt1[, V1], ][, Unique := "N2"] 
# res <- rbind(common, unique1, unique2, fill = TRUE) 

Kleines Update nach @Cath, nur zur Verdeutlichung.

allMerged <- merge(dt1, dt2, by = "V1", all = TRUE) %>% 
    .[, RowSum := rowSums(.SD, na.rm = TRUE), .SDcols = grep("V2", names(.))] %>% 
    .[, Unique := ((is.na(V2.x) + 2*is.na(V2.y)))] 

print(allMerged) 
+0

Danke für die Antwort. – user3253470

+1

ah-ah, ich wusste nicht warum (oh warum) Ich musste "as.numeric" auf meinen 'is.na' Test setzen, wenn ich es wirklich nicht wollte, aber es war nur eine Frage der Vorsicht der erste '!' hat den ganzen "Satz" nicht negiert :-) – Cath

+1

Ich wäre vorsichtig, da Sie jedes '(! is.na (V2.x))' in geschweiften Klammern einfügen müssen, wenn nicht, werden Sie es tun Ende mit dem logischen Vektor TRUE/FALSE. Ohne '!' Ist es nicht der Fall, was einfacher ist, denke ich. –