2014-04-27 11 views
5

Poniżej jest podzbiorem moich danych:R: obliczanie offsetu różnic między elementami w ramce danych, z tym samym identyfikatorem

> head(dt) 

    name start  end 
1: 1 3195984 3197398 
2: 1 3203519 3205713 
3: 2 3204562 3207049 
4: 2 3411782 3411982 
5: 2 3660632 3661579 
6: 3 3638391 3640590 

dt <- data.frame(name = c(1, 1, 2, 2, 2, 3), start = c(3195984, 
3203519, 3204562, 3411782, 3660632, 3638391), end = c(3197398, 
3205713, 3207049, 3411982, 3661579, 3640590)) 

że aby obliczyć inną wartość: różnica między końcem współrzędnych linii N i rozpocząć współrzędną linii n + 1, ale tylko wtedy, gdy oba elementy mają wspólną nazwę. Aby rozwinąć to, co chcę wynikające ramka danych wyglądać:

name start  end dist 
1: 1 3195984 3197398 
2: 1 3203519 3205713 -6121 
3: 2 3204562 3207049 
4: 2 3411782 3411982 −204733 
5: 2 3660632 3661579 −248650 
6: 3 3638391 3640590 

Powód chcę, aby to zrobić jest to, że szukam wartości dist, które są pozytywne. Jednym ze sposobów, w jaki próbowałem tego dokonać, jest przesunięcie współrzędnych początkowych i końcowych, ale wtedy pojawia się problem, w którym porównuję rzeczy o różnych nazwach.

Jak to zrobić w R?

+0

Czy to 'data.table' zamiast' data.frame'? Wygląda na to od sposobu drukowania nazw rzędów. Jeśli tak, to otwiera kilka innych opcji odpowiedzi. – thelatemail

+0

@mail '' class (dt) 'daje:' [1] "data.frame" '. Czy najlepiej byłoby spróbować przekonwertować na 'data.table'? – reedms

+0

Nie, niekoniecznie są one nieco inne pod względem możliwych rozwiązań. – thelatemail

Odpowiedz

5

data.table rozwiązanie może być dobre tutaj:

library(data.table) 
dt <- as.data.table(dt) 
dt[, dist := c(NA, end[-(length(end))] - start[-1]) , by=name] 
dt 

# name start  end dist 
#1: 1 3195984 3197398  NA 
#2: 1 3203519 3205713 -6121 
#3: 2 3204562 3207049  NA 
#4: 2 3411782 3411982 -204733 
#5: 2 3660632 3661579 -248650 
#6: 3 3638391 3640590  NA 

Zakładając, że dane są sortowane, można również z podstawowymi funkcjami R:

dt$dist <- unlist(
    by(dt, dt$name, function(x) c(NA, x$end[-(length(x$end))] - x$start[-1])) 
) 
+0

Otrzymuję "nie-numeryczny argument dla operatora binarnego" za pomocą tego kodu. Uważam, że mój początek i koniec są uważane za czynniki. Czy poprawnym sposobem na naprawienie tego byłoby użycie 'length (jak.numeric (as.character (end))) w kodzie? – reedms

+0

Jeśli masz dane liczbowe, które są zapisywane jako czynnik, powinienem ustawić go jako numeryczny przed wykonaniem dalszych obliczeń: 'dat $ start <- as.numeric (as.character (dat $ start))' itd. Uważaj jednak na to, jakie dane wyrzucisz z tą konwersją. – thelatemail

1

Korzystanie dplyr (z kredytu @thelatemail obliczania dist):

library(dplyr) 

dat.new <- dt %.% 
    group_by(name) %.% 
    mutate(dist = c(NA, end[-(length(end))] - start[-1])) 
+0

@ the mail - good pickup. – alexwhan

0

Oto inne rozwiązanie dplyr:

dt %.% group_by(name) %.% mutate(dist = lag(end) - start) 

podając:

Source: local data frame [6 x 4] 
Groups: name 

    name start  end dist 
1 1 3195984 3197398  NA 
2 1 3203519 3205713 -6121 
3 2 3204562 3207049  NA 
4 2 3411782 3411982 -204733 
5 2 3660632 3661579 -248650 
6 3 3638391 3640590  NA 
Powiązane problemy