2016-06-24 4 views
7

I sofort ein Beispiel geben, nehme jetzt Ich habe 3 Arrays a, b, c wieWie finden Sie fortlaufende Nummern unter mehreren Arrays?

a = c(3,5) 
b = c(6,1,8,7) 
c = c(4,2,9) 

I fähig sein muss ich unter ihnen aufeinander folgenden Tripletts zu extrahieren, e.,

c(1,2,3),c(4,5,6) 

Aber das war nur ein Beispiel, ich hätte einen größeren Datensatz mit sogar mehr als 10 Arrays, muss daher in der Lage sein, die aufeinanderfolgende Serie der Länge zehn zu finden.

So könnte jemand einen Algorithmus zur Verfügung stellen, um allgemein die aufeinanderfolgende Reihe von Länge 'n' unter 'n' Anordnungen zu finden.

Ich mache eigentlich dieses Zeug in R, also ist es vorzuziehen, wenn Sie Ihren Code in R geben. Doch Algorithmus aus jeder Sprache ist mehr als willkommen.

+3

Muss jedes Element in einem Triplet aus verschiedenen Arrays stammen? Wird '{2,3,4}' als gültiges Triplett betrachtet? – Psidom

+0

Ja! , {2,3,4}, {6,7,8} oder {7,8,9} ist nicht gültig. –

Antwort

7

Reorganisieren Sie die Daten zuerst in eine Liste mit Wert und Array-Nummer. Sortieren Sie die Liste; Sie müssten smth wie:

1-2 
2-3 
3-1 (i.e. " there' s a three in array 1") 
4-3 
5-1 
6-2 
7-2 
8-2 
9-3 

Dann Schleife die Liste, ob es tatsächlich n aufeinanderfolgende Zahlen sind, dann prüfen, ob diese

unterschiedliche Array Zahlen hatte
+0

Tolle Idee (upvoted), es könnte nur eine Schwierigkeit geben, wenn die gleiche Zahl in mehr Vektoren ist, aber es ist einfach, die Lösung anzupassen, um das zu berücksichtigen :) – digEmAll

5

Hier ist ein Ansatz. Dies setzt voraus, dass es keine Unterbrechungen in der Reihenfolge der Beobachtungen in der Anzahl der Gruppen gibt. Hier die Daten.

N <- 3 
a <- c(3,5) 
b <- c(6,1,8,7) 
c <- c(4,2,9) 

Dann kombiniere ich sie zusammen und Ordnung durch die Beobachtungen

dd <- lattice::make.groups(a,b,c) 
dd <- dd[order(dd$data),] 

Jetzt habe ich für die Zeilen in dieser Tabelle sehen, wo alle drei Gruppen vertreten sind

idx <- apply(embed(as.numeric(dd$which),N), 1, function(x) { 
    length(unique(x))==N 
}) 

Dann können wir das sehen Triplets mit

lapply(which(idx), function(i) { 
    dd[i:(i+N-1),] 
}) 

# [[1]] 
# data which 
# b2 1  b 
# c2 2  c 
# a1 3  a 
# 
# [[2]] 
# data which 
# c1 4  c 
# a2 5  a 
# b1 6  b 
+0

Das funktionierte perfekt für das gegebene Beispiel. Aber könntest du mir helfen, eine Gruppe zu bilden, da ich 'N' Anzahl von Arrays habe, alles als Liste in einer Liste. –

2

Hier ist eine Brute-Force-Methode mit expand.grid und drei Vektoren, wie in dem Beispiel

# get all combinations 
df <- expand.grid(a,b,c) 

combn Verwendung Differenz für jede paarweise Kombination zu berechnen.

# get all parwise differences 
myDiffs <- combn(names(df), 2, FUN=function(x) abs(x[1]-x[2])) 

# subset data using `rowSums` and `which` 
df[which(rowSums(myDiffs == 1) == ncol(myDiffs)-1), ] 

df[which(rowSums(myDiffs == 1) == ncol(myDiffs)-1), ] 
    Var1 Var2 Var3 
2  5 6 4 
11 3 1 2 
+0

Haben Sie irgendwelche Ideen, um 'N' Liste in expand.grid() -Methode zu übergeben? –

+0

Ich habe gerade versucht und 'expand.grid' wird eine Liste von Vektoren akzeptieren. Sie können die Vektoren in einer Liste mit 'mget' und' ls' sammeln. Spiele mit meiner Antwort auf [diesen Beitrag] (http://stackoverflow.com/questions/17499013/how-do-i-make-a-list-of-data-frames) herum, um eine solche Liste zu erstellen. – lmo

1

ich ein wenig zusammen rekursive Funktion gehackt haben, das wird Finde alle aufeinanderfolgenden Triplets unter so vielen Vektoren, wie du passierst (mindestens drei müssen passieren). Es ist wahrscheinlich ein wenig grob, aber scheint zu funktionieren.

Die Funktion verwendet die Ellipse ... zum Übergeben von Argumenten. Daher wird es viele Argumente (d. H. Numerische Vektoren) benötigen, die Sie angeben, und sie in die Liste items einfügen. Dann befindet sich der kleinste Wert unter jedem übergebenen Vektor zusammen mit seinem Index.

Dann werden die Indizes der Vektoren, die dem kleinsten Triplet entsprechen, erzeugt und iteriert, wobei eine for() Schleife verwendet wird, in der die Ausgabewerte an den Ausgabevektor out übergeben werden.Die Eingabevektoren in items werden beschnitten und erneut rekursiv in die Funktion übernommen. Nur wenn alle Vektoren NA sind, d. H. Es gibt keine weiteren Werte in den Vektoren, gibt die Funktion das Endergebnis zurück.

Die Funktion kann aufgerufen werden, indem die Eingabevektoren als Argumente übergeben werden.

# input vectors 
a = c(3,5) 
b = c(6,1,8,7) 
c = c(4,2,9) 

# find all the triplets using our function 
y <- tripl(a,b,c) 

Das Ergebnis ist eine Liste, die alle neccesary Informationen enthält, wenn auch ungeordnet.

print(y) 
# [[1]] 
# [1] 1 2 3 
# 
# [[2]] 
# [1] 4 5 6 
# 
# [[3]] 
# [1] 7 9 NA 
# 
# [[4]] 
# [1] 8 NA NA 

Bestellung alles kann sapply() getan werden:

# put everything in order 
sapply(y, function(x){x[order(x)]}) %>% t 
#  [,1] [,2] [,3] 
# [1,] 1 2 3 
# [2,] 4 5 6 
# [3,] 7 9 NA 
# [4,] 8 NA NA 

Die Sache ist, dass es nur ein Wert pro Vektor verwendet Drillinge zu finden. Es wird daher das aufeinanderfolgende Triplett c(6,7,8) unter z. c(6,7,11), c(8,9,13) und c(10,12,14). In diesem Fall würde c(6,8,10) zurückgegeben (siehe unten).

a<-c(6,7,11) 
b<-c(8,9,13) 
c<-c(10,12,14) 

y <- tripl(a,b,c) 
sapply(y, function(x){x[order(x)]}) %>% t 
#  [,1] [,2] [,3] 
# [1,] 6 8 10 
# [2,] 7 9 12 
# [3,] 11 13 14 
Verwandte Themen