2016-10-28 6 views
1

Angenommen, ich habe Datenrahmen und ich möchte sehen, ob jeder gegebene Wert in einer gegebenen Spalte gleich dem Wert in der nächsten Reihe einer zweiten Spalte ist?übereinstimmende Werte über Spalten

Ich kann es für 1 Spiel, aber ich versuche, es für den gesamten Datenrahmen zu tun:

match(dataset$co1[i], dataset$co1[i+1]) # where i is a given row # 

Test-Daten-Set:

case <- c("A", "B", "C", "A", "A", "A" ,"B", "C", "B", "A") 
col1 <- c(1, 100, 50, 600, 29, 72, 7, 64, 15, 85) 
col2 <- c(600, 7, 64, 29, 57, 85, 12, 82, 71, 34) 
dataset <- data.frame(case, col1, col2) 

Ich würde auch gerne tun dieser Fall. Ich habe versucht zu sehen, ob ich die Match-Zeile in eine by-Anweisung schreiben könnte, aber ich habe Schwierigkeiten herauszufinden, wie man entlang einer Spalte indexiert.

Irgendwelche Ratschläge?

+1

Ich bin verwirrt über die erwartete Ausgabe für das Beispiel. Es gibt keine Zeilen, in denen ein Match gefunden würde, oder? – Frank

+0

Sie wollten sagen: "Übereinstimmung (Datensatz $ col1 [i], Datensatz $ col2 [i + 1])" richtig? – useR

+0

Vergessen Sie nicht, eine Antwort zu akzeptieren, wenn Sie es hilfreich finden :) – useR

Antwort

0

Wie @Frank darauf hingewiesen hat, würde es auf der Grundlage Ihrer übereinstimmenden Bedingung und Ihres bereitgestellten Datasets keine Übereinstimmungen geben. Zu demonstrativen Zwecken habe ich Ihren Datensatz modifiziert, um zu zeigen, dass meine Lösung wirklich funktioniert. Hier ist eine einfache Art und Weise mit dplyr:

# Modified dataset 
case <- c("A", "B", "C", "A", "A", "A" ,"B", "C", "B", "A") 
col1 <- c(1, 100, 50, 600, 29, 72, 7, 64, 15, 85) 
col2 <- c(600, 7, 64, 1, 600, 85, 100, 82, 71, 34) 
dataset <- data.frame(case, col1, col2) 
> dataset 
    case col1 col2 
1  A 1 600 
2  B 100 7 
3  C 50 64 
4  A 600 1 
5  A 29 600 
6  A 72 85 
7  B 7 100 
8  C 64 82 
9  B 15 71 
10 A 85 34 

Beachten Sie, dass ich die 4. Reihe von col2 auf 1 geändert, 5. Zeile 600 und die siebte Zeile 100. Auf diese Weise die 4. Reihe von col2 mit 1. passen würde von Spalte 1, Spalte 5 stimmt mit Spalte 4 überein, und Spalte 7 stimmt mit Spalte 2 überein, wenn übereinstimmend mit Fall. Außerdem würde nur die fünfte Zeile von Spalte 2 mit der Spalte von Spalte 1 übereinstimmen, wenn nicht von Fall zu Fall übereinstimmt.

library(dplyr) 
dataset %>% 
    add_rownames() %>% 
    mutate(col2 = lead(col2)) %>% 
    filter(col1 == col2) 

# A tibble: 1 × 4 
    rowname case col1 col2 
    <chr> <fctr> <dbl> <dbl> 
1  4  A 600 600 

Dieser Code gibt die Zeilen von col1 zurück, die mit der folgenden Zeile von col2 übereinstimmen. Ich habe add_rownames() hinzugefügt, so dass Sie den ursprünglichen Zeilenindex in dataset kennen. Die lead() Funktion in mutate() ist einfach das Gegenteil von lag() in dplyr (Die generische lag() in der Basis R erlaubt keine verzögerten Nicht-Zeitreihen Vektoren). Es "lags" col2 von k = -1.

dataset %>% 
    add_rownames() %>% 
    group_by(case) %>% 
    mutate(col2 = lead(col2)) %>% 
    filter(col1 == col2) 

Source: local data frame [3 x 4] 
Groups: case [2] 

    rowname case col1 col2 
    <chr> <fctr> <dbl> <dbl> 
1  1  A  1  1 
2  2  B 100 100 
3  4  A 600 600 

von group_by() hinzufügen, können Sie das gleiche tun, sondern von „Fall“. Wie Sie sehen können, werden die übereinstimmenden Zeilen wie erwartet zurückgegeben.

Wenn Sie nicht dplyr aus irgendeinem Grund verwenden möchten, hier ist eine generische Lösung:

## No group by case 
# Lag col2 (Call the lagged column col3) 
dataset$col3 = c(dataset$col2[-1], NA) 

dataset$match = mapply(function(x, y) match(x, y, nomatch = FALSE), 
         dataset$col1, dataset$col3) 

> dataset[dataset$match == 1,] 
    case col1 col2 col3 match 
4 A 600 1 600  1 

## Group by case 
# Split dataset into groups 
dataList = split(dataset, case) 

dataMatched = lapply(dataList, function(x){ 
    x$col2 = c(x$col2[-1], NA) 
    x$match = mapply(function(x, y) match(x, y, nomatch = FALSE), 
      x$col1, x$col2) 
    return(x) 
}) 

resultierende Liste/Datenrahmen:

> dataMatched 
$A 
    case col1 col2 match 
1  A 1 1  1 
4  A 600 600  1 
5  A 29 85  0 
6  A 72 34  0 
10 A 85 NA  0 

$B 
    case col1 col2 match 
2 B 100 100  1 
7 B 7 71  0 
9 B 15 NA  0 

$C 
    case col1 col2 match 
3 C 50 82  0 
8 C 64 NA  0 

> unsplit(dataMatched, case) 
    case col1 col2 match 
1  A 1 1  1 
2  B 100 100  1 
3  C 50 82  0 
4  A 600 600  1 
5  A 29 85  0 
6  A 72 34  0 
7  B 7 71  0 
8  C 64 NA  0 
9  B 15 NA  0 
10 A 85 NA  0 
Verwandte Themen