Skip to content

Commit

Permalink
Closes #592 -- setcolorder now handles incomplete specifications auto…
Browse files Browse the repository at this point in the history
…matically

amend tests/implementation per jan
  • Loading branch information
MichaelChirico committed Dec 5, 2016
1 parent 6706882 commit 32aab12
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 10 deletions.
2 changes: 2 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

1. `indices()` function gain new argument `vectors` default `FALSE`, when `TRUE` provided then list of vectors is returned, single vector refers to single index. Closes #1589.

2. `setcolorder` allows incomplete specification of new order (chosen columns are moved to the front), [#592](https://github.com/Rdatatable/data.table/issues/592). Thanks @MichaelChirico for the PR.

#### BUG FIXES

#### NOTES
Expand Down
24 changes: 16 additions & 8 deletions R/data.table.R
Original file line number Diff line number Diff line change
Expand Up @@ -2569,22 +2569,30 @@ setnames <- function(x,old,new) {
invisible(x)
}

setcolorder <- function(x,neworder)
setcolorder <- function(x, neworder)
{
if (any(duplicated(neworder))) stop("neworder contains duplicates")
# if (!is.data.table(x)) stop("x is not a data.table")
if (length(neworder)!=length(x)) stop("neworder is length ",length(neworder)," but x has ",length(x)," columns.")
if (length(neworder) != length(x)) {
if (length(neworder) > length(x))
stop("neworder is length ", length(neworder),
" but x has only ", length(x), " columns.")
#if shorter than length(x), pad by the missing
# elements (checks below will catch other mistakes)
neworder = c(neworder, setdiff(if (is.character(neworder)) names(x)
else seq_along(x), neworder))
}
if (is.character(neworder)) {
if (any(duplicated(neworder))) stop("neworder contains duplicate column names")
if (any(duplicated(names(x)))) stop("x has some duplicated column name(s): ",paste(names(x)[duplicated(names(x))],collapse=","),". Please remove or rename the duplicate(s) and try again.")
o = as.integer(chmatch(neworder,names(x)))
if (any(is.na(o))) stop("Names in neworder not found in x: ",paste(neworder[is.na(o)],collapse=","))
if (any(duplicated(names(x)))) stop("x has some duplicated column name(s): ", paste(names(x)[duplicated(names(x))], collapse=","), ". Please remove or rename the duplicate(s) and try again.")
o = as.integer(chmatch(neworder, names(x)))
if (any(is.na(o))) stop("Names in neworder not found in x: ", paste(neworder[is.na(o)], collapse=","))
} else {
if (!is.numeric(neworder)) stop("neworder is not a character or numeric vector")
o = as.integer(neworder)
m = !(o %in% seq_len(length(x)))
if (any(m)) stop("Column numbers in neworder out of bounds: ",paste(o[m],collapse=","))
if (any(m)) stop("Column numbers in neworder out of bounds: ", paste(o[m], collapse=","))
}
.Call(Csetcolorder,x,o)
.Call(Csetcolorder, x, o)
invisible(x)
}

Expand Down
6 changes: 5 additions & 1 deletion inst/tests/tests.Rraw
Original file line number Diff line number Diff line change
Expand Up @@ -1442,7 +1442,6 @@ DT = data.table(a=1:2,b=3:4,c=5:6)
test(495, setcolorder(DT,c(2,1,3)), data.table(b=3:4,a=1:2,c=5:6))
test(496, setcolorder(DT,c(2,1,3)), data.table(a=1:2,b=3:4,c=5:6))
test(497, setcolorder(DT,c("c","a","b")), data.table(c=5:6,a=1:2,b=3:4))
test(498, setcolorder(DT,"a"), error="neworder is length")
test(498.1, setcolorder(DT,c("d","a","b")), error="Names in neworder not found in x: d")


Expand Down Expand Up @@ -9789,6 +9788,11 @@ indices(DT, vectors = TRUE)
test(1749.1, indices(DT), c("A__B","A","B"))
test(1749.2, indices(DT, vectors = TRUE), list(c("A","B"),"A","B"))

# allow incomplete specification in setcolorder, #592
DT = data.table(a = 1:3, b = 2:4, c = 3:5)
test(1750.1, names(setcolorder(DT, "b")), c("b", "a", "c"))
test(1750.2, names(setcolorder(DT, c(2, 3))), c("a", "c", "b"))
test(1750.3, setcolorder(DT, 1:4), error = "x has only")

##########################

Expand Down
5 changes: 4 additions & 1 deletion man/setcolorder.Rd
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ setcolorder(x, neworder)
}
\arguments{
\item{x}{ A \code{data.table}. }
\item{neworder}{ Character vector of the new column name ordering. May also be column numbers. }
\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}. }
}
\details{
To reorder \code{data.table} columns, the idiomatic way is to use \code{setcolorder(x, neworder)}, instead of doing \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 All @@ -30,6 +30,9 @@ DT = data.table(A=sample(3, 10, TRUE),
B=sample(letters[1:3], 10, TRUE), C=sample(10))

setcolorder(DT, c("C", "A", "B"))

#incomplete specification
setcolorder(DT, "A")
}
\keyword{ data }

0 comments on commit 32aab12

Please sign in to comment.