Skip to content

Commit 014dafb

Browse files
Add skip_absent to setcolorder (#6044)
* Mention the 2023 data.table community survey * Add skip_absent to setcolorder * Update NEWS * Pass skip_absent to colnamesInt * Revert * Fix * Add test * Update NEWS * Improve performance * Update man/setcolorder.Rd * style changes * Add tests * Clarify NEWS entry * Reword * data.table style * fix NEWS ordering * missing '}' in Rd * style * style * add as author --------- Co-authored-by: Michael Chirico <[email protected]> Co-authored-by: Michael Chirico <[email protected]>
1 parent 23dac21 commit 014dafb

File tree

5 files changed

+21
-4
lines changed

5 files changed

+21
-4
lines changed

DESCRIPTION

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,5 +98,6 @@ Authors@R: c(
9898
person("Christian", "Wia", role="ctb"),
9999
person("Elise", "Maigné", role="ctb"),
100100
person("Vincent", "Rocher", role="ctb"),
101-
person("Vijay", "Lulla", role="ctb")
101+
person("Vijay", "Lulla", role="ctb"),
102+
person("Aljaž", "Sluga", role="ctb")
102103
)

NEWS.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ rowwiseDT(
6565

6666
4. `patterns()` in `melt()` combines correctly with user-defined `cols=`, which can be useful to specify a subset of columns to reshape without having to use a regex, for example `patterns("2", cols=c("y1", "y2"))` will only give `y2` even if there are other columns in the input matching `2`, [#6498](https://github.com/Rdatatable/data.table/issues/6498). Thanks to @hongyuanjia for the report, and to @tdhock for the PR.
6767

68+
5. `setcolorder()` gains `skip_absent` to ignore unrecognized columns (i.e. columns included in `neworder` but not present in the data), [#6044, #6068](https://github.com/Rdatatable/data.table/pull/6044). Default behavior (`skip_absent=FALSE`) remains unchanged, i.e. unrecognized columns result in an error. Thanks to @sluga for the suggestion and @sluga & @Nj221102 for the PRs.
69+
6870
## BUG FIXES
6971

7072
1. `fwrite()` respects `dec=','` for timestamp columns (`POSIXct` or `nanotime`) with sub-second accuracy, [#6446](https://github.com/Rdatatable/data.table/issues/6446). Thanks @kav2k for pointing out the inconsistency and @MichaelChirico for the PR.

R/data.table.R

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2736,15 +2736,16 @@ setnames = function(x,old,new,skip_absent=FALSE) {
27362736
invisible(x)
27372737
}
27382738

2739-
setcolorder = function(x, neworder=key(x), before=NULL, after=NULL) # before/after #4358
2739+
setcolorder = function(x, neworder=key(x), before=NULL, after=NULL, skip_absent=FALSE) # before/after #4358
27402740
{
27412741
if (is.character(neworder))
27422742
check_duplicate_names(x)
27432743
if (!is.null(before) && !is.null(after))
27442744
stopf("Provide either before= or after= but not both")
27452745
if (length(before)>1L || length(after)>1L)
27462746
stopf("before=/after= accept a single column name or number, not more than one")
2747-
neworder = colnamesInt(x, neworder, check_dups=FALSE) # dups are now checked inside Csetcolorder below
2747+
neworder = colnamesInt(x, neworder, check_dups=FALSE, skip_absent=skip_absent) # dups are now checked inside Csetcolorder below
2748+
neworder = neworder[neworder != 0] # tests 498.11, 498.13 fail w/o this
27482749
if (length(before))
27492750
neworder = c(setdiff(seq_len(colnamesInt(x, before) - 1L), neworder), neworder)
27502751
if (length(after))

inst/tests/tests.Rraw

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1604,6 +1604,18 @@ test(498.03, setcolorder(DT, 1, after=3), data.table(b=2, c=3, a=1))
16041604
test(498.04, setcolorder(DT, 3, before=1), data.table(a=1, b=2, c=3))
16051605
test(498.05, setcolorder(DT, 1, before=1, after=1), error="Provide either before= or after= but not both")
16061606
test(498.06, setcolorder(DT, 1, before=1:2), error="before=/after= accept a single column name or number, not more than one")
1607+
# skip_absent, #6044
1608+
test(498.07, setcolorder(DT, skip_absent='TRUE'), error='TRUE or FALSE')
1609+
test(498.08, setcolorder(DT, skip_absent=1), error='TRUE or FALSE')
1610+
test(498.09, setcolorder(DT, skip_absent=c(TRUE, FALSE)), error='TRUE or FALSE')
1611+
test(498.10, setcolorder(DT, c('d', 'c', 'b', 'a')), error='non-existing column')
1612+
test(498.11, setcolorder(DT, c('d', 'c', 'b', 'a'), skip_absent=TRUE), data.table(c=3, b=2, a=1))
1613+
test(498.12, setcolorder(DT, 4:1), error='non-existing column')
1614+
test(498.13, setcolorder(DT, 4:1, skip_absent=TRUE), data.table(a=1, b=2, c=3))
1615+
test(498.14, setcolorder(DT, c(1, 1, 2, 3), skip_absent=TRUE), error='!=')
1616+
## `c` is not dropped
1617+
test(498.15, setcolorder(DT, neworder='b', skip_absent=TRUE), data.table(b=2, a=1, c=3))
1618+
test(498.16, setcolorder(DT, neworder=c('a', 'b', 'd'), skip_absent=TRUE), data.table(a=1, b=2, c=3))
16071619

16081620
# test first group listens to nomatch when j uses join inherited scope.
16091621
x <- data.table(x=c(1,3,8),x1=10:12, key="x")

man/setcolorder.Rd

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,13 @@
99
}
1010

1111
\usage{
12-
setcolorder(x, neworder=key(x), before=NULL, after=NULL)
12+
setcolorder(x, neworder=key(x), before=NULL, after=NULL, skip_absent=FALSE)
1313
}
1414
\arguments{
1515
\item{x}{ A \code{data.table}. }
1616
\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}. }
1717
\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. }
18+
\item{skip_absent}{ Logical, default \code{FALSE}. If \code{neworder} includes columns not present in \code{x}, \code{TRUE} will silently ignore them, whereas \code{FALSE} will throw an error. }
1819
}
1920
\details{
2021
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.

0 commit comments

Comments
 (0)