2017-06-10 51 views
7

Próbowałem usunąć wiersze w data.frame, gdzie wartość w kolumnie posn nie była w zakresach podanych w innym data.frame, z funkcją łączenia non-equi data.table.Jak zachować łączenie kolumny bez zmian w sprzężeniu non-equi do data.table?

Oto jak wygląda moje dane:

library(data.table) 
df.cov <- 
    structure(list(posn = c(1, 2, 3, 165, 1000), att = c("a", "b", 
    "c", "d", "e")), .Names = c("posn", "att"), row.names = c(NA, 
    -5L), class = "data.frame") 
df.exons <- 
    structure(list(start = c(2889, 2161, 277, 164, 1), end = c(3329, 
    2826, 662, 662, 168)), .Names = c("start", "end"), row.names = c(NA, 
    -5L), class = "data.frame") 

setDT(df.cov) 
setDT(df.exons) 

df.cov 
# posn att 
# 1: 1 a 
# 2: 2 b 
# 3: 3 c 
# 4: 165 d 
# 5: 1000 e 
df.exons # ranges of `posn` to include 
# start end 
# 1: 2889 3329 
# 2: 2161 2826 
# 3: 277 662 
# 4: 164 662 
# 5:  1 168 

Oto, co starałem:

df.cov[df.exons, on = .(posn >= start, posn <= end), nomatch = 0] 
# posn att posn.1 
# 1: 164 d 662 
# 2: 1 a 168 
# 3: 1 b 168 
# 4: 1 c 168 
# 5: 1 d 168 

Można zobaczyć, że kolumna w df.covposn również ulega zmianie. Oczekiwany wynik wygląda tak:

# posn att 
# 1: 165 d 
# 2: 1 a 
# 3: 2 b 
# 4: 3 c 
# 5 165 d 
# the row order doesn't matter. I'll sort by posn latter. 
# It is also fine if the duplicated rows are removed, otherwise I'll do this in next step. 

Jak mogę uzyskać pożądaną wyjście z data.table non-equi przyłączyć?

+0

'df.cov [df.cov [df.exons, w = (Posn> = początek, Posn <= koniec) nomatch = 0, która = PRAWDA]] 'Złożyłem FR dla tego rodzaju podzbioru https://github.com/Rdatatable/data.table/issues/2158 (nie jestem pewien, czy to ma sens, ponieważ nikt nie ma odpowiedział na to jeszcze). Aby rzucić duplikaty, zastosuj po prostu 'unique' do wektora' which' przed podzbiorem. – Frank

+0

Zapytałem nieco pokrewnego pytania jakiś czas temu: [Użyj 'j', aby wybrać kolumnę łączyć' x' i wszystkie jej kolumny non-join] (https://stackoverflow.com/questions/42329157/use-j- to-select-the-join-column-of-x-and-all-its-non-join-columns) – Henrik

+1

@Frank, dziękuję. Oto, do czego ostatecznie doszedłem w oparciu o twoje: 'df.cov [sort (unique (df.cov [df.exons, on =. (Posn> = start, posn <= end), nomatch = 0, which = TRUE]))] '. Czytam twoje FR i myślę, że taka funkcja byłaby naprawdę pomocna w wielu przypadkach takich jak ta. – mt1022

Odpowiedz

6

Można również użyć %inrange%:

df.cov[posn %inrange% df.exons] 

co skutkuje:

posn att 
1: 1 a 
2: 2 b 
3: 3 c 
4: 165 d 

Jak widać pozostawia Wartości posn -column niezmienione.


Inną, choć dłuższe, możliwo.

df.exons[df.cov 
     , on = .(start <= posn, end >= posn) 
     , mult ='first' 
     , nomatch = 0 
     , .(posn = i.posn, att)][] 
+1

Tak łatwo. Nigdy wcześniej nie zauważyłem tej tajnej funkcji. – mt1022

+0

@ mt1022 dodano inną opcję – Jaap

+0

Nie spodziewałem się, że poświęcisz czas na znalezienie rozwiązania, które pasuje ściśle do mojej prośby w poście. Bardzo dziękuję za podejście "non-equi join". – mt1022