2016-07-08 18 views
1

Ich habe ein Datenframe bestehend aus zwei Spalten ("Delta" & "Let"). Werte innerhalb von "let" repräsentieren einzigartige Faktoren. Werte innerhalb von "Delta" repräsentieren eine ganze Zahl zwischen 0-1000000.R: Erweitern Datenrahmen durch Pairing-Werte innerhalb eines Minimalkriteriums

Musterdatenrahmen (DF) enthält:

df <- data.frame(delta = c(0,6,2,3,4,8,6,1,1,4), 
       let = c("a","b","c","d","e","f","g","h","i","j")) 

df 
    delta let 
1  0 a 
2  6 b 
3  2 c 
4  3 d 
5  4 e 
6  8 f 
7  6 g 
8  1 h 
9  1 i 
10  4 j 

Um zu erklären, df: die ganze Zahl innerhalb von "delta" bezeichnet die Differenz in der Zeit (Minuten) zwischen aufeinander folgenden Faktoren innerhalb "let". Zum Beispiel hat "b" eine Zeitdifferenz von 6 Minuten von "a", "c" hat eine Zeitdifferenz von 2 Minuten von "b" und "d" hat eine Zeitdifferenz von 3 Minuten von "c" ... usw.

Ich möchte einen neuen Datenrahmen (df2) generieren, der Werte von "let" basierend auf einer minimalen Zeitdifferenz (minDelta ≤ 2 Minuten) "paart"; in folgenden Ausgabe führt:

minDelta <- 2 # minutes 

df2 
    let let.pairs 
1 a  NA 
2 b   c 
3 c   b 
4 d  NA 
5 e  NA 
6 f  NA 
7 g   h 
8 g   i 
9 h   g 
10 h   i 
11 i   g 
12 i   h 
13 j  NA 

DF2 Um zu erklären: „a“ paart nicht mit irgendeinem anderen Wert innerhalb „let“ Bei einem gegebenen minimales Zeitdifferenzkriterium von ≤ MinDelta. Daher ist "let.pairs" für "a" "NA". Umgekehrt paart sich "b" mit "c" (und umgekehrt), weil ihre Zeitdifferenz (delta = 2) ≤ minDelta ist. Beachten Sie, dass "g" mit "h" (delta = 1) und mit "i" (delta = 1 + 1) kombiniert wird.

Ich würde mich über jede Unterstützung mit dem R-Code freuen, um das erklärte Ziel zu erreichen.

Vielen Dank im Voraus!

Antwort

1

Eine weitere Option

x <- setNames(cumsum(df$delta), df$let) 

pairs <- NULL 
for (lag in seq(length(x) - 1L)) { 
    tmp <- which(diff(x, lag) <= minDelta) + lag 
    if (length(tmp)) 
     pairs[[lag]] <- cbind(names(x)[tmp], names(x)[tmp - lag]) 
    else 
     break 
} 
pairs <- do.call(rbind, pairs) 
pairs <- rbind(pairs, pairs[, c(2, 1)]) 
pairs <- rbind(pairs, cbind(setdiff(names(x), pairs[, 1]), NA)) 
pairs <- pairs[order(pairs[, 1]), ] 
data.frame(let=pairs[, 1], let.pairs=pairs[, 2]) 
# let let.pairs 
#1 a  <NA> 
#2 b   c 
#3 c   b 
#4 d  <NA> 
#5 e  <NA> 
#6 f  <NA> 
#7 g   h 
#8 g   i 
#9 h   g 
#10 h   i 
#11 i   h 
#12 i   g 
#13 j  <NA> 
+0

sehr vielen Dank! Dies scheint gut zu funktionieren. – Ross

0

Sie können eine rekursive Funktion schreiben, das Problem zu nähern:

find.pair <- function(df) { 
    if(nrow(df) == 0) data.frame() 
    else { 
     pairs = df$let[c(F, cumsum(df$delta[-1]) <= 2)] 
     if(length(pairs) == 0) { 
      rbind(data.frame(let = df$let[1], let.pairs = NA), 
        find.pair(df[-1,])) 
     } 
     else { 
      rbind(data.frame(let = df$let[1], 
          let.pairs = pairs), 
        data.frame(let = pairs, 
          let.pairs = df$let[1]), 
        find.pair(df[-1,]))  
     } 
    } 
} 

Dies ist nicht genau das, was Sie brauchen, aber es ist eine Idee. Eine Feinabstimmung mit dem Ergebnisdatenrahmen sollte Ihnen das gewünschte Ergebnis bringen.

find.pair(df) 
# let let.pairs 
# 1 a  <NA> 
# 2 b   c 
# 3 c   b 
# 4 c  <NA> 
# 5 d  <NA> 
# 6 e  <NA> 
# 7 f  <NA> 
# 8 g   h 
# 9 g   i 
# 10 h   g 
# 11 i   g 
# 12 h   i 
# 13 i   h 
# 14 i  <NA> 
# 15 j  <NA>