2016-12-11 4 views
0

ich ein Datum mit drei Spalten wieZusammenführung und Zählen ähnliche Strings

Inputdf<-structure(list(df1 = structure(c(4L, 5L, 2L, 1L, 3L), .Label = c("P61160,P61158,O15143,O15144,O15145,P59998,O15511", 
"P78537,Q6QNY1,Q6QNY0", "Q06323,Q9UL46", "Q92793,Q09472,Q9Y6Q9,Q92831", 
"Q92828,Q13227,O15379,O75376,O60907,Q9BZK7"), class = "factor"), 
    df2 = structure(c(3L, 2L, 5L, 4L, 1L), .Label = c("", "P61158,O15143,O15144", 
    "Q06323,Q9UL46", "Q6QNY0", "Q92828"), class = "factor"), 
    df3 = structure(c(5L, 4L, 3L, 2L, 1L), .Label = c("", "O15511", 
    "Q06323,Q9UL46", "Q6QNY0", "Q92793,Q09472"), class = "factor")), .Names = c("df1", 
"df2", "df3"), class = "data.frame", row.names = c(NA, -5L)) 

Ich versuche, Ähnliche Strings in diesen Daten zum Beispiel zu finden

in df1, ich habe die erste Reihe I Q92793,Q09472,Q9Y6Q9,Q92831 habe dann sehe ich DF2 und DF3 und sehen, ob eines dieser Mitglieder in dort dann in diesem Beispiel sind, stelle ich die folgenden Daten

df1 df2 df3 Numberdf1  df2  df3 
1 0 1 4    0  Q92793,Q09472 

df1 1 bedeutet die erste Zeile von df1 df2 0 bedeutet, es hatte keine Ähnlichkeit df3 1, bedeutet die erste Zeile von df3 hat Ähnlichkeit mit df1 Zeile 1 Numberdf1, es ist die Anzahl der Zeichenfolgen durch eine , getrennt ist, die ist 4 DF2 ist 0, da es keine ähnlichen Zeichenfolge Akkorden war df2 df3 Q92793 ist, Q09472, die die Zeichenfolge einfügen, die

ein Wunsch Ausgabe wie folgt aussieht unten

out<- structure(list(df1 = 1:5, df2 = c(0L, 3L, 4L, 2L, 1L), df3 = c(1L, 
0L, 2L, 4L, 3L), Numberdf1 = c(4L, 6L, 2L, 7L, 2L), df2.1 = structure(c(1L, 
5L, 4L, 2L, 3L), .Label = c("0", "P61158,O15143,O15144", "Q06323,Q9UL46", 
"Q6QNY0", "Q92828"), class = "factor"), df3.1 = structure(c(5L, 
1L, 4L, 2L, 3L), .Label = c("0", "O15511", "Q06323,Q9UL46", "Q6QNY0", 
"Q92793,Q09472"), class = "factor")), .Names = c("df1", "df2", 
"df3", "Numberdf1", "df2.1", "df3.1"), class = "data.frame", row.names = c(NA, 
-5L)) 

die unten Funktion hier ähnlich waren tut nicht funktionieren, verwenden Sie diese Daten beispielsweise als Eingabe

Inputdf1<- structure(list(df1 = structure(c(2L, 3L, 1L), .Label = c("Q06323,Q9UL46", 
"Q92793,Q09472,Q9Y6Q9,Q92831", "Q92828,Q13227,O15379,O75376,O60907,Q9BZK7" 
), class = "factor"), df2 = structure(1:3, .Label = c("P25788,P25789", 
"Q92828, O60907, O75376", "Q9UL46, Q06323"), class = "factor"), 
    df3 = structure(c(2L, 1L, 3L), .Label = c("Q92831, Q92793, Q09472", 
    "Q9BZK7, Q92828, O75376, O60907", "Q9UL46, Q06323"), class = "factor")), .Names = c("df1", 
"df2", "df3"), class = "data.frame", row.names = c(NA, -3L)) 
+0

Könnten Sie das 'Bereich führt zum überprüfen? Sind diese Werte korrekt? In der zweiten Reihe von "out", wie hast du df2.1 als 'Q92828', wenn der Wert von' df2' 'P61158, O15143, O15144' ist und ähnlich für die letzte Zeile – akrun

+0

@akrun die Zeile von df1 ist wichtig , könnte es mit Zeile 2 oder 3 oder 10 von df2 ähnlich sein. In diesem Fall hatte die zweite Zeile von df1 eine ähnliche Zeichenfolge in der dritten Zeile von df2. Ist es jetzt klar? – nik

Antwort

1

Dies funktioniert für Ihr Beispiel:

# First convert factors to strings to lists 
Inputdf[] = lapply(Inputdf, as.character) 
Inputdf[] = lapply(Inputdf, function(col) sapply(col, function(x) unlist(strsplit(x,',')))) 

not.empty = function(x) length(x) > 0 
out = data.frame() 

for (r in 1:nrow(Inputdf)) { 
    df2.intersect = lapply(Inputdf$df2, intersect, Inputdf$df1[[r]]) 
    df3.intersect = lapply(Inputdf$df3, intersect, Inputdf$df1[[r]]) 

    out[r, 'df1'] = r 
    out[r, 'df2'] = Position(not.empty, df2.intersect, nomatch=0) 
    out[r, 'df3'] = Position(not.empty, df3.intersect, nomatch=0) 
    out[r, 'Numberdf1'] = length(Inputdf$df1[[r]]) 
    out[r, 'df2.1'] = paste(Find(not.empty, df2.intersect, nomatch=0), collapse=',') 
    out[r, 'df3.1'] = paste(Find(not.empty, df3.intersect, nomatch=0), collapse=',') 
} 

out 
# df1 df2 df3 Numberdf1    df2.1   df3.1 
# 1 1 0 1   4     0 Q92793,Q09472 
# 2 2 3 0   6    Q92828    0 
# 3 3 4 2   3    Q6QNY0  Q6QNY0 
# 4 4 2 4   7 P61158,O15143,O15144  O15511 
# 5 5 1 3   2  Q06323,Q9UL46 Q06323,Q9UL46 

Hinweis: Find und Position identifizieren die zunächst nur Spiel. Wenn es mehrere Übereinstimmungen gibt, verwenden Sie which.

EDIT

Version für mehrere Übereinstimmungen

Buchhaltung
Inputdf[] = lapply(Inputdf, as.character) 
Inputdf[] = lapply(Inputdf, function(col) sapply(col, function(x) unlist(strsplit(x,',\\s*')))) 

not.empty = function(x) length(x) > 0 
out = data.frame() 

for (r in 1:nrow(Inputdf)) { 
    df2.intersect = lapply(Inputdf$df2, intersect, Inputdf$df1[[r]]) 
    df3.intersect = lapply(Inputdf$df3, intersect, Inputdf$df1[[r]]) 

    out[r, 'df1'] = r 
    out[r, 'df2'] = paste(which(sapply(df2.intersect, not.empty)), collapse=',') 
    out[r, 'df3'] = paste(which(sapply(df3.intersect, not.empty)), collapse=',') 
    out[r, 'Numberdf1'] = length(Inputdf$df1[[r]]) 
    out[r, 'df2.1'] = paste(unique(unlist(df2.intersect)), collapse=',') 
    out[r, 'df3.1'] = paste(unique(unlist(df3.intersect)), collapse=',') 
} 

out[out==""] = "0" 
+0

gibt es mehrere Ähnlichkeit, wäre es möglich, auf diese Weise zu ändern, weil auf echte Daten, gibt es keine richtigen Antworten – nik

+0

Ich postete ein anderes Beispiel oben, um Ihnen zu zeigen, dass es nicht funktioniert !! Ich weiß nicht, wo das Problem ist – nik

+0

@nik Im neuen Beispiel gibt es zusätzliche Leerzeichen zwischen den Elementen ("A, B" vs "A, B") – sirallen

Verwandte Themen