2013-03-22 5 views
6

Doing seryjnej między zaludnionym data.table i innym, że jest pusta wprowadza jeden NA wiersz wynikowy data.table:merge.data.table ze wszystkimi = True wprowadza wiersz NA. Czy to jest poprawne?

a = data.table(c=c(1,2),key='c') 
b = data.table(c=3,key='c') 
b=b[c!=3] 
b 
# Empty data.table (0 rows) of 1 col: c 
merge(a,b,all=T) 
#  c 
# 1: NA 
# 2: 1 
# 3: 2 

Dlaczego? Spodziewałem się, że powróci tylko rzędy data.table a, jak to robi z merge.data.frame:

> merge.data.frame(a,b,all=T,by='c') 
# c 
#1 1 
#2 2 
+0

Więc chcesz połączyć 'a' z pustą tabelą danych' b'. Dlaczego wprowadzasz 'b' w tak niecodzienny sposób? Dlaczego nie używać 'b = data.table()'? – user974514

+0

@ user974514: Chciałem tylko odtworzyć problem tak, jak pojawił się w moim kodzie. Ogólnie rzecz biorąc, 'data.table's w moim kodzie są zapełniane, ale czasami nie, aw moim przypadku tabele są kluczowane, a scalanie naturalnie używa tych kluczy. Prosta 'data.table()' nie odtwarza dokładnie problemu jaki miałem. – vsalmendra

+0

@ user974514, który dałby NULL danych.tabeli (0 wierszy i kolumn) i nie będzie kolumny "klucz". Tak więc połączenie nie byłoby możliwe. – Arun

Odpowiedz

5

Przykładem w tej kwestii jest zbyt prosty, aby pokazać problem, stąd zamieszanie i dyskusja . Używanie dwóch jednokolumnowych data.table s nie wystarczy, aby pokazać, co robi merge!

Oto lepszy przykład:

> a = data.table(P=1:2,Q=3:4,key='P') 
> b = data.table(P=2:3,R=5:6,key='P') 
> a 
    P Q 
1: 1 3 
2: 2 4 
> b 
    P R 
1: 2 5 
2: 3 6 
> merge(a,b) # correct 
    P Q R 
1: 2 4 5 
> merge(a,b,all=TRUE) # correct. 
    P Q R 
1: 1 3 NA 
2: 2 4 5 
3: 3 NA 6 
> merge(a,b[0],all=TRUE) # incorrect result when y is empty, agreed 
    P Q R 
1: NA NA NA 
2: NA NA NA 
3: 1 3 NA 
4: 2 4 NA 
> merge.data.frame(a,b[0],all=TRUE) # correct 
    P Q R 
1 1 3 NA 
2 2 4 NA 

Ricardo dotarł do sedna sprawy i naprawić go w v1.8.9. Z INFORMACJE:

seryjnej nie powraca już do fałszywych NA rzędu (i), w którym Y jest pusty i all.y = prawdą (lub wszystkie = PRAWDA), #2633. Dziękuję do Vinicius Almendra za zgłoszenie. Test został dodany.

0

Biorąc zdefiniować a i b w drodze. Proste użycie rbind(a,b) zwróci tylko wiersze a.

Jeśli jednak chcesz scalić tabelę danych NULL b z inną niepustą tabelą danych a, istnieje inne podejście. Miałem podobny problem, gdy musiałem scalić różne tabele danych w różnych pętlach. Użyłem tego obejścia.

#some loop that returns data.table named a 
    #another loop starts 
    if(all.equal(a,b<-data.table())==TRUE){ 
    b<-a 
    next 
    } 
    merge(a,b,c("Factor1","Factor2")) 

To mi pomogło, może ci też pomoże.

+0

Niestety, nie otrzymałem twojego oświadczenia końcowego. Jeśli 'a' jest' data.table' o wymiarach '0 o 0' (jak' b'), to przypisujesz 'b' do' a'. Czemu? I nie używasz 'copy (a)'. To po prostu przypisze referencję, a nie skopiuje a do b. Nie rozumiem tego. – Arun

+0

Załóżmy, że masz pętlę, w której wypełniasz plik data.table 'a'. Więc nie jest pusty. Ale na końcu pętli chcesz połączyć ją z inną tabelą danych 'b', która może być pusta w pierwszej iteracji, ale staje się niepusta w drugim. To rozwiązuje to obejście. – user974514

+0

Głosowanie w dół jest ode mnie, jeśli mógłbyś wyjaśnić (lub edytować), byłbym szczęśliwy, gdyby głosowałem w górę). – Arun

1

wszystkie: logiczne; all = PRAWDA jest skrótem, aby zapisać ustawienie zarówno all.x = TRUE, jak i all.y = TRUE.

all.x: logiczny; jeśli TRUE, do wyjścia zostaną dodane dodatkowe wiersze, po jednym dla każdego wiersza w x, który nie ma pasującego wiersza w y. Te wiersze będą miały 'NA w kolumnach , które są zwykle wypełniane wartościami od y. Wartością domyślną jest FALSE, więc tylko wiersze z danymi pochodzącymi zarówno z x, jak i y są uwzględniane w danych wyjściowych.

all.y: logiczny; analogiczne do all.x powyżej.

To jest wzięte z data.table documentation. Aby uzyskać więcej informacji, zobacz opis argumentów dla funkcji merge.

Myślę, że to odpowiada na twoje pytanie.

+0

może mógłbyś wypróbować 'ifelse (dim (b) [1] == 0, scalenie (a, b, all.x = T), scalenie (a, b, all.y = T))' lub coś podobnego –

+1

Ta dokumentacja jest taka sama jak "merge.data.frame", która zachowuje się inaczej. Nie rozumiem, dlaczego pełne sprzężenie zewnętrzne z pustym stołem powinno dodać wiersz NA. – vsalmendra

0

To należy się spodziewać, jak merge.data.frameall=T jest full outer join, więc masz wszystkie klucze z obu tabel zobaczyć about merge

+0

Tabela 'b' zawiera pusty klucz (bez wierszy), który różni się od klucza o wartości NA. – vsalmendra

+2

Być może znalazłeś błąd, ponieważ jest to bardzo nietypowy przypadek, możesz pisać na liście danych? – statquant

+0

Dzięki. Właśnie przedłożyłem to i inny błąd, który znalazłem, również związany z pustym plikiem data.table ... – vsalmendra

Powiązane problemy