2013-07-10 40 views
9

在下面的例子如何防止合并和重新排序的列

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

我想这样做x <- merge(x, y),但问题是,merge()重新排序列,使得by列(食品)是第一位的。 我该如何防止这种情况,并让merge(x, y)使用x的相同列顺序,并且只需插入新变量(isFruit)作为第三列(即“code,food,isFruit”而不是“food,code,isFruit”)?

我试过这个,无济于事:

merge(x, y, sort = F) 

我的解决方法是做到这一点之后

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

我认为你的解决方法是解决问题。 – joran

+4

...虽然看起来plyr包中的'join'不会重新排列列。 – joran

回答

17

这是你的基础的解决办法的一个仿制版本:

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

您可以在自定义函数包裹。例如:

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

再例如:

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

编辑我用@Eddi思路来套ORD的默认值。

+2

-1,因为这不会增加任何东西到OP - OP想要的是**没有**不得不手动指定顺序 – eddi

+1

@eddi好赶上,即使我不同意downvote(我觉得它有点尖锐)。我的想法是创建一个扩展合并函数的函数。我使用你的好主意编辑我的答案,以设置订单的默认值。 – agstudy

+0

+1现在它回答OP :) – eddi

11

plyr让一切变得简单:

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'一次解决了我的一堆问题。谢谢你的提示! – dsb

0

如果仅在一列带来的,并希望将其追加持续那么也许merge是矫枉过正并且您可以仅使用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 

(没有开关投入合并功能来做你所要求的。)

+0

感谢您的输入,但我的真实数据涉及两列数十个数据框。 –