如何防止合并对列重新排序

问题描述 投票:0回答:5

在下面的例子中

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)]
r sorting merge
5个回答
33
投票

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

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

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

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 idea来设置ord的默认值。


2
投票

如果您只引入一列并想将其添加到最后,那么

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
投票

我过去使用过另一种解决方法:

x$target <- merge(x, y, by = "key", all = T)$target

这当然有缺点:

  • 它一次仅合并一列。
  • 这是手动的,如果您忘记在两个地方手动更改列名称,很容易出错。
  • 需要
    all=TRUE
    来防止任何未合并的元素。
© www.soinside.com 2019 - 2024. All rights reserved.