2017-04-10 5 views
3

Ich bin ein Anfänger R-Programmierer. Ich habe eine folgende Reihe von Punkten.So wählen Sie eindeutigen Punkt

df <- data.frame(x = c(1 , 2, 3, 4), y = c(6 , 3, 7, 5)) 
df <- df %>% mutate(k = 1) 
df <- df %>% full_join(df, by = 'k') 
df <- subset(df, select = c('x.x', 'y.x', 'x.y', 'y.y')) 
df 

Gibt es eine Möglichkeit für "einzigartige" Punkte auszuwählen? (Die Reihenfolge der Punkte keine Rolle)

EDIT:

x.x y.x x.y y.y 
1 6 2 3 
2 3 3 7 
. 
. 
. 

(ich die 2 bis 7 geändert, das Problem zu klären)

+0

Meine erwartete Ausgabe 6 Reihen sein würde (4 wählen 2) die Kombinationen von allen Punkten. Ich werde einen Schnitt machen. –

+0

sollen alle 4 Werte in der Zeile, die in Zeile genommen werden sollen, inakcount sein? oder nur ein x- und y-Wert? –

+0

Meine "Objekte" für meine 4 wählen 2 Problem sollte die Punktpaare "x.x" und "y.x" sein –

Antwort

4

Mit data.table (und Arbeiten aus dem OP anfänglichen df):

library(data.table) 
setDT(df) 

df[, r := .I ] 
df[df, on=.(r > r), nomatch=0] 


    x y r i.x i.y 
1: 2 3 1 1 6 
2: 3 2 1 1 6 
3: 4 5 1 1 6 
4: 3 2 2 2 3 
5: 4 5 2 2 3 
6: 4 5 3 3 2 

Dies ist ein auf die Zeilennummern "non-equi join". In x[i, on=.(r > r)] bezieht sich die linke r auf die Reihe in x und die rechte auf eine Reihe von i. Die Spalten mit der Bezeichnung i.* stammen aus i.

Data.table Joins, die die Form x[i] haben, verwenden Sie i, um Zeilen von x nachzuschlagen. Die nomatch=0 Option löscht Zeilen von i, die keine Übereinstimmungen finden.

+0

Für mein Lernen, was wäre r =: .Ich meine? –

+1

Oh, das erzeugt nur die Zeilennummer, genau wie 'mutate (r = row_number())' in dplyr, außer dass es durch Referenz zur Tabelle hinzugefügt wird, so dass das Ergebnis nicht mit '<-' versehen werden muss. – Frank

+0

Ohhh machst du eine nicht equi beitreten auf den Datensatz. durch data.table –

1

Sie können die Funktion duplicated.matrix() von Base verwenden, um die Zeilen zu finden, die kein Duplikator sind - was tatsächlich bedeutet, dass es Eindeutigkeiten gibt. Wenn Sie die Funktion duplicated() aufrufen, müssen Sie klarstellen, dass Sie nur die ersten Doppelpunkte verwenden möchten. Mit diesem Aufruf prüfen Sie, welche Zeile eindeutig ist. In einem zweiten Schritt rufen Sie Ihren Datenrahmen für diese Zeilen mit allen Spalten auf.

unique_lines = !duplicated.matrix(df[,c(1,2)]) 
df[unique_lines,] 
2

Im tidyverse, können Sie mit tidyr::crossing die Selbst verbinden, indem Sie ein wenig Arbeit sparen. Wenn Sie Zeilenindizes Pre-Join hinzufügen mag, einen einfachen filter Anruf reduziert:

library(tidyverse) 

df %>% mutate(i = row_number()) %>% # add row index column 
    crossing(., .) %>% # Cartesian self-join 
    filter(i < i1) %>% # reduce to lower indices 
    select(-i, -i1) # remove extraneous columns 

## x y x1 y1 
## 1 1 6 2 3 
## 2 1 6 3 7 
## 3 1 6 4 5 
## 4 2 3 3 7 
## 5 2 3 4 5 
## 6 3 7 4 5 

oder in alle Basis R,

df$m <- 1 
df$i <- seq(nrow(df)) 
df <- merge(df, df, by = 'm') 
df[df$i.x < df$i.y, c(-1, -4, -7)] 

## x.x y.x x.y y.y 
## 2 1 6 2 3 
## 3 1 6 3 7 
## 4 1 6 4 5 
## 7 2 3 3 7 
## 8 2 3 4 5 
## 12 3 7 4 5 
+1

Für base R auch: 'cb = combn (nrow (df), 2); cbind (df [cb [1,],], df [cb [2,],]) ' – Frank

+0

Ich bekomme einen Fehler mit der dplyr-Methode. Es besagt, dass es sich um doppelte Spalten handelt, wenn es zum Filterschritt kommt. Gibt es eine Möglichkeit, die Spalten zu differenzieren? –

+0

@Frank Ja, das ist eine viel einfachere Option. – alistaire

Verwandte Themen