I wrote a function to append columns onto (into) a data.frame. It allows you to name the column as well, and does a few checks...
append_col <- function(x, cols, after=length(x)) {
x <- as.data.frame(x)
if (is.character(after)) {
ind <- which(colnames(x) == after)
if (any(is.null(ind))) stop(after, "not found in colnames(x)\n")
} else if (is.numeric(after)) {
ind <- after
}
stopifnot(all(ind <= ncol(x)))
cbind(x, cols)[, append(1:ncol(x), ncol(x) + 1:length(cols), after=ind)]
}
examples:
# create data
df <- data.frame("a"=1:5, "b"=6:10)
# append column
append_col(df, list(c=1:5))
# append after an column index
append_col(df, list(c=1:5), after=1)
# or after a named column
append_col(df, list(c=1:5), after="a")
# multiple columns / single values work as expected
append_col(df, list(c=NA, d=4:8), after=1)
(One advantage of calling cbind at the end of the function and indexing is that characters within the data.frame are not coerced to factors as would be the case if using as.data.frame(append(x, cols, after=ind))
)