suffixes
in merge
works only on common column names. Is there anyway to extend this to the rest of the columns as well without manually updating co
This is an interesting question, and I doubt that extending merge
would be a straightforward solution unless Matt Dowle and Co. think it's something worth implementing in merge.data.table
.
Here's one approach that came to mind:
DTs <- c("df1", "df2")
suffixes <- seq_along(DTs)
for (i in seq_along(DTs)) {
Name <- setdiff(colnames(get(DTs[i])), "a")
setnames(get(DTs[i]), Name, paste(Name, suffixes[i], sep = "."))
}
merge(df1, df2, by = "a") # Will obviously work as you expect now
Try the following:
colnames(
mergeWithSuffix(df1,df2, by = 'a', suffixes = c("1","2"))
)
[1] "a" "b.1" "d.1" "d.2"
Notice that the original data.frames
are unharmed.
colnames(df1)
[1] "a" "b" "d"
colnames(df2)
[1] "a" "d"
The functions are as follows
require(data.table)
mergeWithSuffix <- function(x, y, by, suffixes=NULL, ...) {
# Add Suffixes
mkSuffix(x, suffixes[[1]], merge.col=by)
mkSuffix(y, suffixes[[2]], merge.col=by)
# Merge
ret <- merge(x, y, by = by, suffixes = NULL, ...)
# Remove Suffixes
undoSuffix(x, suffixes[[1]], merge.col=by)
undoSuffix(y, suffixes[[2]], merge.col=by)
return(ret)
}
mkSuffix <- function(x, sfx, sep=".", merge.col=NULL) {
nms <- setdiff(names(x), merge.col)
setnames(x, nms, paste(nms, sfx, sep=".") )
}
undoSuffix <- function(x, sfx, sep=".", merge.col=NULL) {
nms <- setdiff(names(x), merge.col)
setnames(x, nms, sub(paste0(get("sep"), sfx, "$"), "", nms))
}
Notice that setnames
works by reference, so the overhead is almost negligible. Also, as discussed elsewhere, this works equally well on data.frames and data.table
A simple solution:
mrg<-(merge(df1,df2, by = 'a', suffixes = c("1","2")))
setnames(mrg,paste0(names(mrg),ifelse(names(mrg) %in% setdiff(names(df1),names(df2)),"1","")))
setnames(mrg,paste0(names(mrg),ifelse(names(mrg) %in% setdiff(names(df2),names(df1)),"2","")))
> names(mrg)
[1] "a" "b1" "d1" "d2"
Edit: thanks to comments by Ricardo Saporta for cleaning this up considerably and teaching me a few new tips!