R 在多个列上合并会导致奇怪的顺序

R 在多个列上合并会导致奇怪的顺序,r,sorting,merge,R,Sorting,Merge,当两个数据帧被一个数字列合并时(默认情况下),它们按该列作为数字排序。但是,如果两个数字列被用作,则会导致不同的排序(事实上,似乎数字列被转换为字符串并按此排序)。这是预期的,还是一个bug 例如,考虑以下两个数据帧: A <- data.frame(a = 1:12, b = 1, x = runif(12)) B <- data.frame(a = 1:12, b = 1, y = runif(12)) A使用dplyr包,我们可以得到以下结果 library("dplyr",

当两个数据帧被一个数字列合并时(默认情况下),它们按该列作为数字排序。但是,如果两个数字列被用作
,则会导致不同的排序(事实上,似乎数字列被转换为字符串并按此排序)。这是预期的,还是一个bug

例如,考虑以下两个数据帧:

A <- data.frame(a = 1:12, b = 1, x = runif(12))
B <- data.frame(a = 1:12, b = 1, y = runif(12))

A使用
dplyr
包,我们可以得到以下结果

library("dplyr", lib.loc="~/R/win-library/3.2")

full_join(A, B, by=c("a", "b"))

     a b          x           y
    1   1 1 0.39907404 0.700782559
    2   2 1 0.84429488 0.600727090
    3   3 1 0.32232471 0.141495156
    4   4 1 0.74214210 0.262601640
    5   5 1 0.92944116 0.779255689
    6   6 1 0.10902661 0.001185645
    7   7 1 0.46336478 0.961711785
    8   8 1 0.58396008 0.211824751
    9   9 1 0.63126074 0.422233784
    10 10 1 0.09995935 0.179069642
    11 11 1 0.40832159 0.581116173
    12 12 1 0.48440814 0.004372634

我想这是
merge
的一个特性,而不是一个bug

merge
源代码的检查表明,在使用多个列进行合并的情况下,“键”列通过使用
paste()
在内部组合成一个向量

例如,数据帧
a
中的
a
b
列将由字符串
“1\r1”“2\r1”“3\r1”“4\r1”“5\r1”“6\r1”“7\r1”“8\r1”“9\r1”“10\r1”“11\r1”“12\r1”表示

merge
使用此字符串对结果数据帧进行排序,这就是它以字母顺序结束的方式

在只合并一列的情况下,不需要使用
粘贴
,因此使用列的原始类型执行排序

这是
merge
的相关源代码片段(在R控制台中运行
merge.data.frame
可以获得全文,不带括号)

if(l.b==1L){

bx禁止在merge
merge(A,B,by=c('A','B'),sort=F)中使用排序功能
我的问题与谢谢相同。您的评论(和来源)完整地解释行为。我同意,也许这不是一个bug,因为
merge
的文档对于行为应该是什么并不完全清楚(帮助说明“默认情况下,行是按公共列的字典顺序排序的”).然而,在我看来,大多数人都会期待我所期待的行为。是否值得将其作为R的一个bug/功能(或者是像
merge
这样基本的东西本质上冻结了)来提出?
    if (l.b == 1L) {
        bx <- x[, by.x]
        if (is.factor(bx)) 
            bx <- as.character(bx)
        by <- y[, by.y]
        if (is.factor(by)) 
            by <- as.character(by)
    }
    else {
        if (!is.null(incomparables)) 
            stop("'incomparables' is supported only for merging on a single column")
        bx <- x[, by.x, drop = FALSE]
        by <- y[, by.y, drop = FALSE]
        names(bx) <- names(by) <- paste0("V", seq_len(ncol(bx)))
        bz <- do.call("paste", c(rbind(bx, by), sep = "\r"))
        bx <- bz[seq_len(nx)]
        by <- bz[nx + seq_len(ny)]
    }