当两个数据框由数字列合并时(默认情况下),它们按该列排序为数字。但是,如果将两个数字列用作by
,那么它会导致不同的排序(事实上,似乎数字列被转换为字符串并按此排序)。这是预期的,还是一个错误?
例如,请考虑以下两个数据框:
A <- data.frame(a = 1:12, b = 1, x = runif(12))
B <- data.frame(a = 1:12, b = 1, y = runif(12))
然后merge(A, B, by = 'a')
产生具有值a
的数据帧,其值为1,2,...,9,10,11,12(即,预期的数字排序)。但是,merge(A, B, by = c('a', 'b'))
会生成一个数据框,其中列a
的值为1,10,11,12,2,3,...,8,9(即与{{1相同的顺序) }})。
答案 0 :(得分:2)
我想这是一个功能,而不是merge
的错误。
检查merge
的源代码表明,在使用多列进行合并的情况下,使用paste()
将“关键”列内部合并到一个向量中。
例如,数据框a
中的列b
和A
将由字符串"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
使用此字符串对结果数据框进行排序,这就是它以字母顺序结束的方式。
如果仅合并一列,则无需使用paste
,因此使用列的原始类型执行排序。
以下是merge
源代码的相关部分(可以通过在R控制台中运行merge.data.frame
无括号来获取全文)
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)] }
答案 1 :(得分:0)
使用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