2014-09-16 39 views
9

Z pewnością nie jest to przeznaczone? Czy jest to coś, co dzieje się w innych częściach funkcjonalności dplyr i czy powinienem się tym przejmować? Uwielbiam wydajność i nienawidzę składni data.table. Czy istnieje alternatywa dla dplyr i data.table, która jest obecnie bezpieczna w użyciu i wciąż wysoka?Nieprawidłowe zachowanie przy użyciu left_join dplyr?

A <- structure(list(ORDER = c(30305720L, 30334659L, 30379936L, 
        30406397L, 30407697L, 30431950L), 
        COST = c("0", "", "11430.52", "20196.279999999999", "0", "10445.99")), 
       .Names = c("ORDER", "COST"), 
       row.names = c(NA, 6L), 
       class = "data.frame") 

B <- structure(list(ORDER = c(30334659, 30379936, 30406397, 30407697, 30431950), 
        AREA = c(0, 2339, 2162, 23040, 475466)), 
       .Names = c("ORDER", "AREA"), 
       row.names = c(4L, 8L, 11L, 12L, 15L), 
       class = c("tbl_df", "tbl", "data.frame")) 

wyniki śmiecie:

left_join(A, B) 
    ORDER COST     AREA 
1 30305720     0 NA 
2 30334659      NA 
3 30379936   11430.52 NA 
4 30406397 20196.279999999999 NA 
5 30407697     0 NA 
6 30431950   10445.99 NA 

wyniki życie:

merge(A, B, all.x=T, all.y=F) 
    ORDER    COST AREA 
1 30305720     0  NA 
2 30334659       0 
3 30379936   11430.52 2339 
4 30406397 20196.279999999999 2162 
5 30407697     0 23040 
6 30431950   10445.99 475466 
+0

Używam wersji R 3.1. – stanekam

+0

Uwaga ta wydaje się być tutaj ponownie przyznana https://github.com/hadley/dplyr/issues/601 – mnel

+1

Zwróć uwagę, że składnia 'data.table'' setDT (A); setDT (B); setkey (A, ORDER) ; setkey (B, ORDER); A [B] 'działa, aby zapewnić" efektywne wyniki ". 'data.table' sprawia, że ​​klucze/grupy są równe w granicach tolerancji maszyny. – mnel

Odpowiedz

10

napisałem coś podobnego na drugi dzień. Myślę, że musisz ustawić ORDER jako numeryczny (lub być może na odwrót). A ma ORDER ma liczbę całkowitą. Ale B ma ORDER jako numeryczny. W tej chwili dplyr prosi o posiadanie zmiennych grupowych w tej samej klasie. Otrzymałem komentarz od użytkownika SO mówiącego, że jest to coś, nad czym pracuje teraz Hadley i jego zespół. Ten problem zostanie rozwiązany w przyszłości.

A$ORDER <- as.numeric(A$ORDER) 
left_join(A,B, by = "ORDER") 

    ORDER    COST AREA 
1 30305720     0  NA 
2 30334659       0 
3 30379936   11430.52 2339 
4 30406397 20196.279999999999 2162 
5 30407697     0 23040 
6 30431950   10445.99 475466 

UPDATE Po wymianie uwag z thelatemail, postanowiłem dodać kilka uwag tutaj.

Przypadek 1: Traktuj kolejności jak numerycznej

A$ORDER <- as.numeric(A$ORDER) 

> left_join(A,B, by = "ORDER") 
    ORDER    COST AREA 
1 30305720     0  NA 
2 30334659       0 
3 30379936   11430.52 2339 
4 30406397 20196.279999999999 2162 
5 30407697     0 23040 
6 30431950   10445.99 475466 

> left_join(B,A, by = "ORDER") 
Source: local data frame [5 x 3] 

    ORDER AREA    COST 
1 30334659  0     
2 30379936 2339   11430.52 
3 30406397 2162 20196.279999999999 
4 30407697 23040     0 
5 30431950 475466   10445.99 

Jeśli masz zamówienie jako całkowitą zarówno A i B, który działa też.

Przykład 2: Leczenie kolejności, jak i całkowitą numeryczny

> left_join(A,B, by = "ORDER") 
    ORDER    COST AREA 
1 30305720     0 NA 
2 30334659      NA 
3 30379936   11430.52 NA 
4 30406397 20196.279999999999 NA 
5 30407697     0 NA 
6 30431950   10445.99 NA 

> left_join(B,A, by = "ORDER") 
Source: local data frame [5 x 3] 

    ORDER AREA    COST 
1 30334659  0     
2 30379936 2339   11430.52 
3 30406397 2162 20196.279999999999 
4 30407697 23040     0 
5 30431950 475466   10445.99 

Jak sugeruje thelatemail liczba całkowita/połączenie numeryczne nie działa. Ale działa kombinacja numeryczna/całkowita.

Biorąc pod uwagę te obserwacje, można bezpiecznie zachować spójność w danej grupie. Ewentualnie, droga do przebycia to merge(). Może obsługiwać liczbę całkowitą i numeryczną.

> merge(A,B, by = "ORDER", all = TRUE) 
    ORDER    COST AREA 
1 30305720     0  NA 
2 30334659       0 
3 30379936   11430.52 2339 
4 30406397 20196.279999999999 2162 
5 30407697     0 23040 
6 30431950   10445.99 475466 

> merge(B,A, by = "ORDER", all = TRUE) 
    ORDER AREA    COST 
1 30305720  NA     0 
2 30334659  0     
3 30379936 2339   11430.52 
4 30406397 2162 20196.279999999999 
5 30407697 23040     0 
6 30431950 475466   10445.99 

Update2 (od 8 listopada 2014)

używam wersji dev dplyr (dplyr_0.3.0.9000), który można pobrać z Github. Powyższy problem został rozwiązany.

left_join(A,B, by = "ORDER") 
#  ORDER    COST AREA 
#1 30305720     0  NA 
#2 30334659       0 
#3 30379936   11430.52 2339 
#4 30406397 20196.279999999999 2162 
#5 30407697     0 23040 
#6 30431950   10445.99 475466 
+1

+1 - pobity do ponczu. Nadal jestem zdumiony, dlaczego 'left_join (B, A)' wydaje się działać dobrze. – thelatemail

+0

@ thesailemail To jest interesująca obserwacja. Jeśli tak, to jest to prawdziwy błąd? – jazzurro

+0

Na pierwszy rzut oka powiedziałbym, że tak. Nie byłoby dla mnie spójne, gdyby łączenie numeryczne/liczbowe zakończyło się niepowodzeniem, ale łączenie numeryczne/całkowite zakończyło się powodzeniem. – thelatemail

-1

Z dokumentacji dplyr:

left_join() zwraca wszystkie wiersze z X i wszystkie kolumny od x i y. Wiersze w x bez dopasowania w y będą miały wartości NA w nowych kolumnach. Jeśli istnieje wiele dopasowań między x i y, zwracane są wszystkie kombinacje dopasowań.

semi_join() zwraca wszystkie wiersze z x, gdzie są dopasowane wartości y, zachowując kolumny tylko z x. Łączenie pół różni się od połączenia wewnętrznego, ponieważ sprzężenie wewnętrzne zwróci jeden wiersz x dla każdego pasującego wiersza y, gdzie łączenie semi nigdy nie powieli wierszy x.

Czy semi_join() jest dla Ciebie wartościową opcją?