2013-07-10 75 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

感謝您的輸入,但我的真實數據涉及兩列數十個數據框。 –