/
setdiff.data.frame.R
63 lines (60 loc) · 1.44 KB
/
setdiff.data.frame.R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#' Computed \code{\link[base]{data.frame}} Differences Using Common Columns
#'
#' Computed \code{\link[base]{data.frame}} differences using common columns.
#'
#' @param x a \code{\link[base]{data.frame}}
#' @param y a \code{\link[base]{data.frame}}
#' @keywords array manip
#' @rdname setdiff
#' @export setdiff
#' @seealso \code{\link[base]{setdiff}}
#' @examples
#' x=data.frame(z1=letters[1:3], x=1:3)
#' y=data.frame(z1=letters[2:4], y=-(2:4))
#' setdiff(x, y)
#' setdiff(y, x)
#'
#' x=data.frame(z1=letters[1:3], z2=letters[1:3], x=1:3)
#' y=data.frame(z1=letters[2:4], z2=letters[2:4], y=-(2:4))
#' setdiff(x, y)
#' setdiff(y, x)
#'
#' x=data.frame(z1=letters[1:3], x=1:3)
#' y=data.frame(z2=letters[2:4], y=-(2:4))
#' setdiff(x, y)
#' setdiff(y, x)
setdiff=function(x, y) UseMethod('setdiff')
#' @return \code{NULL}
#'
#' @rdname setdiff
#' @method setdiff default
#' @S3method setdiff default
setdiff.default=base::setdiff
#' @return \code{NULL}
#'
#' @rdname setdiff
#' @method setdiff data.frame
#' @S3method setdiff data.frame
setdiff.data.frame=function(x, y){
by_names=intersect(names(x), names(y))
l=length(by_names)
if(l == 0L) {
x
} else {
bz=do.call(
'paste'
, c(
rbind(
x[, by_names, drop=F]
, y[, by_names, drop=F]
)
, sep = '\r'
)
)
nx=nrow(x)
bx=bz[seq_len(nx)]
by=bz[-seq_len(nx)]
comm=match(bx, by, 0L)
return(x[comm == 0L,,drop=F])
}
}