如何防止合并重新排序列
Posted
技术标签:
【中文标题】如何防止合并重新排序列【英文标题】:How to prevent merge from reordering columns 【发布时间】:2013-07-08 15:11:46 【问题描述】:在下面的例子中
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,是水果”)?
我试过了,没用:
merge(x, y, sort = F)
我的解决方法是以后再做
x <- x[c(2, 1, 3)]
【问题讨论】:
我认为您的解决方法就是解决方案。 ...虽然 plyr 包中的join
似乎没有重新排序列。
【参考方案1】:
您可以将其包装在您的自定义函数中。例如:
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
EDIT 我使用@Eddi idea 来设置 ord 的默认值。
【讨论】:
-1 因为这不会向 OP 添加任何内容 - OP 想要的是 不必 必须手动指定订单 @eddi 很好,即使我不同意反对票(我觉得有点尖锐)。我的想法是创建一个扩展合并函数的函数。我使用您的好主意编辑我的答案以设置订单的默认值。 @agstudy 你好,如果我有不同名称的数据表(例如 x = DT1,y = DT2)并且我在这些数据表的不同列上合并,则此解决方案不起作用。错误消息:as.vector(x) 中的错误:找不到对象“x”。有道理,因为数据表一开始没有命名为 x 和 y。我试图找到一种解决方法,但没有成功。您知道如何调整解决方案,使其更适用于(更复杂的)数据表合并吗?【参考方案2】: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
【讨论】:
plyr
一下子解决了我的一堆问题。感谢您的提示!【参考方案3】:
这是您的基本解决方法的通用版本:
merge(x, y)[, union(names(x), names(y))]
【讨论】:
请注意,为 col 名称传入union
仅适用于数据帧,而不适用于数据表。
@Serenthia 添加, with = FALSE
为data.table
使用“by.x=”和“by.y=”以及名称不同的列合并时失败。上述解决方法的一个丑陋版本是(使用 OP 修改的示例数据,将“food”和“food2”作为合并列):x <- data.frame(code = 7:9, food = c('banana', 'apple', 'popcorn')) ; y <- data.frame(food2 = c('banana', 'apple', 'popcorn'), isfruit = c('fruit', 'fruit', 'not fruit')) ; byY="food2" ; merge(x, y, by.x="food",by.y=byY)[, union(names(x), subset(names(y), names(y)!=byY))]
【参考方案4】:
如果您只引入一列并想最后附加它,那么merge
可能是多余的,您可以使用match
-[
indexing 方法进行评估:
> 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
(在合并功能中没有任何开关可以满足您的要求。)
【讨论】:
感谢您的输入,但我的真实数据涉及两个数十列的数据框。以上是关于如何防止合并重新排序列的主要内容,如果未能解决你的问题,请参考以下文章
UNION表时如何在Bigquery中重新排列/重新排序嵌套的重复列