2013-07-10 14 views
9

Trong ví dụ sauLàm thế nào để ngăn chặn hợp nhất từ ​​cột sắp xếp lại

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')) 

Tôi muốn làm x <- merge(x, y), nhưng vấn đề là merge() sắp xếp lại các cột để cột by (thức ăn) đến trước. Làm cách nào để ngăn chặn điều này và có merge(x, y) sử dụng cùng thứ tự cột của x và chỉ chèn biến mới (isFruit) làm cột thứ ba (tức là "mã, thực phẩm, isFruit" thay vì "food, code, isFruit")?

Tôi đã cố gắng này, không có kết quả:

merge(x, y, sort = F) 

workaround của tôi là để làm điều này sau đó

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

Tôi nghĩ công việc của bạn xung quanh là giải pháp. – joran

+4

... mặc dù có vẻ như 'join' trong gói plyr không sắp xếp lại các cột. – joran

Trả lời

17

Dưới đây là một phiên bản generic của workaround cơ sở của bạn:

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

Bạn có thể bọc nó trong chức năng tùy chỉnh của bạn. Ví dụ:

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

sau đó ví dụ:

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

EDIT tôi sử dụng ý tưởng @Eddi để thiết lập giá trị mặc định của ord.

+2

-1 bởi vì điều này không thêm bất cứ điều gì cho OP - những gì OP muốn là ** không ** phải xác định thứ tự bằng tay – eddi

+1

@eddi tốt bắt ngay cả khi tôi không đồng ý với downvote (tôi tìm thấy nó một chút sắc nét). Ý tưởng của tôi là tạo ra một hàm mở rộng các hàm kết hợp. Tôi chỉnh sửa câu trả lời của tôi bằng cách sử dụng ý tưởng tốt của bạn để đặt giá trị mặc định của đơn đặt hàng. – agstudy

+0

+1 bây giờ nó trả lời OP :) – eddi

11

plyr làm cho điều này dễ dàng:

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' vừa giải quyết một loạt vấn đề của tôi cùng một lúc. Cảm ơn vì tiền hỗ trợ! – dsb

0

Nếu bạn chỉ mang lại trong một cột và muốn gắn nó kéo dài thì có lẽ merge là overkill và bạn chỉ có thể thực hiện một giải pháp với phương thức lập chỉ mục match - [:

> 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 

(Không có thiết bị chuyển mạch để ném vào chức năng hợp nhất để làm những gì bạn yêu cầu.)

+0

Cảm ơn bạn đã nhập, nhưng dữ liệu thực của tôi liên quan đến hai khung dữ liệu với hàng tá cột. –