Skip to content

Commit

Permalink
Add skip_absent to setcolorder
Browse files Browse the repository at this point in the history
  • Loading branch information
sluga committed Apr 9, 2024
1 parent 898dce3 commit 0abcb02
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 2 deletions.
9 changes: 8 additions & 1 deletion R/data.table.R
Original file line number Diff line number Diff line change
Expand Up @@ -2681,14 +2681,21 @@ setnames = function(x,old,new,skip_absent=FALSE) {
invisible(x)
}

setcolorder = function(x, neworder=key(x), before=NULL, after=NULL) # before/after #4358
setcolorder = function(x, neworder=key(x), before=NULL, after=NULL,skip_absent=FALSE) # before/after #4358
{
if (is.character(neworder) && anyDuplicated(names(x)))
stopf("x has some duplicated column name(s): %s. Please remove or rename the duplicate(s) and try again.", brackify(unique(names(x)[duplicated(names(x))])))
if (!is.null(before) && !is.null(after))
stopf("Provide either before= or after= but not both")
if (length(before)>1L || length(after)>1L)
stopf("before=/after= accept a single column name or number, not more than one")
if (!isTRUEorFALSE(skip_absent))
stopf("skip_absent should be TRUE or FALSE")
if (skip_absent && is.character(neworder)){
neworder = intersect(neworder, colnames(x))
} else if (skip_absent && is.numeric(neworder)){
neworder = intersect(neworder, seq_along(x))
}
neworder = colnamesInt(x, neworder, check_dups=FALSE) # dups are now checked inside Csetcolorder below
if (length(before))
neworder = c(setdiff(seq_len(colnamesInt(x, before) - 1L), neworder), neworder)
Expand Down
8 changes: 8 additions & 0 deletions inst/tests/tests.Rraw
Original file line number Diff line number Diff line change
Expand Up @@ -1567,6 +1567,14 @@ test(498.03, setcolorder(DT, 1, after=3), data.table(b=2, c=3, a=1))
test(498.04, setcolorder(DT, 3, before=1), data.table(a=1, b=2, c=3))
test(498.05, setcolorder(DT, 1, before=1, after=1), error="Provide either before= or after= but not both")
test(498.06, setcolorder(DT, 1, before=1:2), error="before=/after= accept a single column name or number, not more than one")
# skip_absent
test(498.07, setcolorder(DT, skip_absent = 'TRUE'), error = 'TRUE or FALSE')
test(498.08, setcolorder(DT, skip_absent = 1), error = 'TRUE or FALSE')
test(498.09, setcolorder(DT, skip_absent = c(TRUE, FALSE)), error = 'TRUE or FALSE')
test(498.10, setcolorder(DT, c('d', 'c', 'b', 'a')), error = 'non-existing column')
test(498.11, setcolorder(DT, c('d', 'c', 'b', 'a'), skip_absent = TRUE), data.table(c=3, b=2, a=1))
test(498.12, setcolorder(DT, 4:1), error = 'non-existing column')
test(498.13, setcolorder(DT, 4:1, skip_absent = TRUE), data.table(a=1, b=2, c=3))

# test first group listens to nomatch when j uses join inherited scope.
x <- data.table(x=c(1,3,8),x1=10:12, key="x")
Expand Down
3 changes: 2 additions & 1 deletion man/setcolorder.Rd
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,13 @@
}

\usage{
setcolorder(x, neworder=key(x), before=NULL, after=NULL)
setcolorder(x, neworder=key(x), before=NULL, after=NULL,skip_absent=FALSE)
}
\arguments{
\item{x}{ A \code{data.table}. }
\item{neworder}{ Character vector of the new column name ordering. May also be column numbers. If \code{length(neworder) < length(x)}, the specified columns are moved in order to the "front" of \code{x}. By default, \code{setcolorder} without a specified \code{neworder} moves the key columns in order to the "front" of \code{x}. }
\item{before, after}{ If one of them (not both) was provided with a column name or number, \code{neworder} will be inserted before or after that column. }
\item{skip_absent}{ \code{FALSE} (the default) will throw an error if neworder includes columns not present in \code{x}, \code{TRUE} will quietly drop such columns.}
}
\details{
To reorder \code{data.table} columns, the idiomatic way is to use \code{setcolorder(x, neworder)}, instead of doing \code{x <- x[, ..neworder]} (or \code{x <- x[, neworder, with=FALSE]}). This is because the latter makes an entire copy of the \code{data.table}, which maybe unnecessary in most situations. \code{setcolorder} also allows column numbers instead of names for \code{neworder} argument, although we recommend using names as a good programming practice.
Expand Down

0 comments on commit 0abcb02

Please sign in to comment.