14

在下面的例子中

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)]
4

4 回答 4

31

这是您的基本解决方法的通用版本:

merge(x, y)[, union(names(x), names(y))]
于 2013-07-10T19:16:49.407 回答
13

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
于 2013-07-10T19:11:44.633 回答
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 的默认值。

于 2013-07-10T18:17:14.647 回答
1

如果您只引入一列并希望最后附加它,那么可能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

(在合并功能中没有任何开关可以满足您的要求。)

于 2013-07-10T20:10:38.260 回答