2013-07-10 16 views
9

W poniższym przykładzieJak zapobiec scalanie z kolumnami zamianom

x <- data.frame(code = 7:9, food = c('banana', 'apple', 'popcorn')) 
y <- data.frame(food = c('banana', 'apple', 'popcorn'), 
       isfruit = c('fruit', 'fruit', 'not fruit')) 

Chciałbym zrobić x <- merge(x, y), ale problemem jest to, że merge() zmieniać kolejność kolumn tak, że kolumna by (żywności) jest na pierwszym miejscu. Jak mogę temu zapobiec i mam merge(x, y) użyć tej samej kolejności kolumn x i po prostu wstawić nową zmienną (isFruit) jako trzecią kolumnę (tj. "Kod, jedzenie, isFruit" zamiast "jedzenie, kod, isFruit")?

Próbowałem to bezskutecznie:

merge(x, y, sort = F) 

Moje obejście jest zrobić to później

x <- x[c(2, 1, 3)] 
+3

Myślę, że twoja praca wokół jest rozwiązaniem. – joran

+4

... chociaż wydaje się, że 'join' w pakiecie plyr nie zmienia kolejności kolumn. – joran

Odpowiedz

17

Oto generycznych wersji bazowej obejścia:

merge(x, y)[, union(names(x), names(y))] 
6

Można owinąć go w funkcji niestandardowej. Na przykład:

merge.keep <- function(...,ord=union(names(x), names(y)))merge(...)[ord] 

następnie na przykład:

merge.keep(x,y) 
    code food isfruit 
1 8 apple  fruit 
2 7 banana  fruit 
3 9 popcorn not fruit 

EDIT używam @Eddi pomysł, aby ustawić domyślne wartości ord.

+2

-1 ponieważ to nie dodaje niczego do OP - czego OP chce nie ** nie ** musi ręcznie określać zamówienie – eddi

+1

@eddi dobry połów nawet nie zgadzam się ze stanowiskiem (uważam, że jest trochę ostry). Mój pomysł polegał na stworzeniu funkcji rozszerzającej funkcje scalania. Edytuję swoją odpowiedź, używając Twojego dobrego pomysłu, aby ustawić domyślne wartości zamówienia. – agstudy

+0

+1 teraz, gdy odpowiada OP :) – eddi

11

plyr ułatwia to:

x <- data.frame(code = 7:9, food = c('banana', 'apple', 'popcorn')) 
y <- data.frame(food = c('banana', 'apple', 'popcorn'), 
       isfruit = c('fruit', 'fruit', 'not fruit')) 

library(plyr) 
join(x,y) 

     #GOOD 
#Joining by: food 
# code food isfruit 
#1 7 banana  fruit 
#2 8 apple  fruit 
#3 9 popcorn not fruit 

    #BAD 
# merge(x,y) 
#  food code isfruit 
#1 apple 8  fruit 
#2 banana 7  fruit 
#3 popcorn 9 not fruit 
+1

'plyr' właśnie rozwiązał kilka moich problemów naraz. Dzięki za wskazówkę! – dsb

0

Jeśli tylko wprowadzają w jednej kolumnie i chcą dołączyć trwać to może merge jest przesadą i można po prostu wykonać powiązanie z podejściem indeksowania:

> x$isfruit <- y$isfruit[match(y$food, x$food)] 
> x 
    code food isfruit 
1 7 banana  fruit 
2 8 apple  fruit 
3 9 popcorn not fruit 

(Nie ma przełączników do wrzucania funkcji scalania, aby zrobić to, o co prosisz.)

+0

Dzięki za dane wejściowe, ale moje prawdziwe dane obejmują dwie ramki danych z dziesiątkami kolumn. –