Skip to content

Commit

Permalink
various coverage (#3757)
Browse files Browse the repository at this point in the history
  • Loading branch information
mattdowle authored Aug 12, 2019
1 parent 59f49ab commit 30a4fcd
Show file tree
Hide file tree
Showing 7 changed files with 48 additions and 74 deletions.
2 changes: 2 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,8 @@
14. The warning message when using `keyby=` together with `:=` is clearer, [#2763](https://github.com/Rdatatable/data.table/issues/2763). Thanks to @eliocamp.
15. `first` and `last` gain an explicit `n=1L` argument so that it's clear the default is 1, and their almost identical manual pages have been merged into one.


### Changes in [v1.12.2](https://github.com/Rdatatable/data.table/milestone/14?closed=1) (07 Apr 2019)

Expand Down
16 changes: 8 additions & 8 deletions R/last.R
Original file line number Diff line number Diff line change
Expand Up @@ -3,35 +3,35 @@
# This last is implemented this way for compatibility with xts::last which is S3 generic taking 'n' and 'keep' arguments
# We'd like last() on vectors to be fast, so that's a direct x[NROW(x)] as it was in data.table, otherwise use xts's.
# If xts is loaded higher than data.table, xts::last will work but slower.
last = function(x, ...) {
last = function(x, n=1L, ...) {
if (nargs()==1L) {
if (is.vector(x)) {
if (!length(x)) return(x) else return(x[[length(x)]]) # for vectors, [[ works like [
} else if (is.data.frame(x)) return(x[NROW(x),])
}
if(!requireNamespace("xts", quietly = TRUE)) {
tail(x, n = 1L, ...) # nocov
tail(x, n=n, ...) # nocov
} else {
# fix with suggestion from Joshua, #1347
if (!"package:xts" %chin% search()) {
tail(x, n = 1L, ...) # nocov
} else xts::last(x, ...) # UseMethod("last") doesn't find xts's methods, not sure what I did wrong.
tail(x, n=n, ...) # nocov
} else xts::last(x, n=n, ...) # UseMethod("last") doesn't find xts's methods, not sure what I did wrong.
}
}

# first(), similar to last(), not sure why this wasn't exported in the first place...
first = function(x, ...) {
first = function(x, n=1L, ...) {
if (nargs()==1L) {
if (is.vector(x)) {
if (!length(x)) return(x) else return(x[[1L]])
} else if (is.data.frame(x)) return(x[1L,])
}
if(!requireNamespace("xts", quietly = TRUE)) {
head(x, n = 1L, ...) # nocov
head(x, n=n, ...) # nocov
} else {
# fix with suggestion from Joshua, #1347
if (!"package:xts" %chin% search()) {
head(x, n = 1L, ...) # nocov
} else xts::first(x, ...) # nocov
head(x, n=n, ...) # nocov
} else xts::first(x, n=n, ...) # nocov
}
}
2 changes: 1 addition & 1 deletion R/test.data.table.R
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ test.data.table = function(verbose=FALSE, pkg="pkg", silent=FALSE, with.other.pa
# Sys.setlocale("LC_CTYPE", "") # just for CRAN's Mac to get it off C locale (post to r-devel on 16 Jul 2012)

cat("getDTthreads(verbose=TRUE):\n") # for tracing on CRAN; output to log before anything is attempted
print(getDTthreads(verbose=TRUE)) # print output of getDTthreads() verbatim as simply as possible; e.g. without depending on data.table for formatting
print(invisible(getDTthreads(verbose=TRUE))) # print output of getDTthreads() verbatim as simply as possible; e.g. without depending on data.table for formatting
cat("test.data.table() running:", fn, "\n") # print fn to log before attempting anything on it (in case it is missing); on same line for slightly easier grep
env = new.env(parent=.GlobalEnv)
assign("testDir", function(x) file.path(fulldir, x), envir=env)
Expand Down
5 changes: 3 additions & 2 deletions R/transpose.R
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ transpose = function(l, fill=NA, ignore.empty=FALSE, keep.names=NULL, make.names
if (!is.null(make.names)) {
stopifnot(length(make.names)==1L)
if (is.character(make.names)) {
make.names=chmatch(make.names, names(l))
if (is.na(make.names))
m = chmatch(make.names, names(l))
if (is.na(m))
stop("make.names='",make.names,"' not found in names of input")
make.names = m
} else {
make.names = as.integer(make.names)
if (is.na(make.names) || make.names<1L || make.names>length(l))
Expand Down
21 changes: 12 additions & 9 deletions inst/tests/tests.Rraw
Original file line number Diff line number Diff line change
Expand Up @@ -7778,6 +7778,7 @@ test(1571.3, names(tstrsplit(X$a, "", fixed=TRUE, names=letters[1:4])), letters[
test(1571.4, tstrsplit(X$a, "", fixed=TRUE, keep=c(2,4)), list(c("B", "E"), c(NA, "G")))
test(1571.5, tstrsplit(X$a, "", fixed=TRUE, keep=c(2,7)), error="should contain integer")
test(1571.6, tstrsplit(X$a, "", fixed=TRUE, keep=c(2,4), names=letters[1:5]), error="is not equal to")
test(1571.7, tstrsplit(X$a, "", fixed=TRUE, names=1), error="'names' must be TRUE/FALSE or a character vector")

# fix for #1367, quote="" argument in use. Using embedded quotes in the example below reads the
# first two columns as one. I couldn't find a way to avoid introducing quote argument.
Expand Down Expand Up @@ -9895,6 +9896,7 @@ test(1686.2, DT[, .(V1=A,B)], DT[, c(.(get("A")), .SD), .SDcols="B"])
test(1687.1, first(1:5), 1L)
test(1687.2, first(data.table(x=1:5, y=6:10)), data.table(x=1L, y=6L))
test(1687.3, first(integer(0L)), integer(0L))
test(1687.4, first(1:5, 2), 1:2)

if (test_bit64) {
# fix for #1385 and part of #1459
Expand Down Expand Up @@ -15510,17 +15512,18 @@ test(2072.067, fifelse(c(TRUE, NA, TRUE, FALSE, FALSE, FALSE), factor(NA), facto
factor(c(NA,NA,NA,NA,NA,NA)))

DT = data.table(x=1:5, y=6:10)
test(2073.1, transpose(DT, keep.names="rn"),
test(2073.01, transpose(DT, keep.names="rn"),
ans<-data.table(rn=c('x','y'), V1=c(1L, 6L), V2=c(2L, 7L), V3=c(3L, 8L), V4=c(4L, 9L), V5=c(5L, 10L)))
test(2073.2, transpose(DT, keep.names=TRUE), error="either NULL.*name of the first column of the result")
test(2073.3, transpose(ans, make.names="rn"), DT)
test(2073.4, transpose(ans, keep.names="rn", make.names="rn"), data.table(rn=paste0("V",1:5), x=1:5, y=6:10))
test(2073.02, transpose(DT, keep.names=TRUE), error="either NULL.*name of the first column of the result")
test(2073.03, transpose(ans, make.names="rn"), DT)
test(2073.04, transpose(ans, make.names="notthere"), error="make.names='notthere' not found in names of input")
test(2073.05, transpose(ans, keep.names="rn", make.names="rn"), data.table(rn=paste0("V",1:5), x=1:5, y=6:10))
L = list(a=1:3, rn=LETTERS[1:3], b=4:6)
test(2073.5, transpose(L, make.names=0), error="make.names=0 is out of range [1,ncol=3]")
test(2073.6, transpose(L, make.names=4), error="make.names=4 is out of range [1,ncol=3]")
test(2073.7, transpose(L, make.names=NA), error="make.names=NA is out of range [1,ncol=3]")
test(2073.8, transpose(L, make.names=2), list(A=INT(1,4), B=INT(2,5), C=INT(3,6)))
test(2073.9, transpose(L, make.names=2, keep.names='foo'), list(foo=c("a","b"), A=INT(1,4), B=INT(2,5), C=INT(3,6)))
test(2073.06, transpose(L, make.names=0), error="make.names=0 is out of range [1,ncol=3]")
test(2073.07, transpose(L, make.names=4), error="make.names=4 is out of range [1,ncol=3]")
test(2073.08, transpose(L, make.names=NA), error="make.names=NA is out of range [1,ncol=3]")
test(2073.09, transpose(L, make.names=2), list(A=INT(1,4), B=INT(2,5), C=INT(3,6)))
test(2073.10, transpose(L, make.names=2, keep.names='foo'), list(foo=c("a","b"), A=INT(1,4), B=INT(2,5), C=INT(3,6)))


###################################
Expand Down
34 changes: 0 additions & 34 deletions man/first.Rd

This file was deleted.

42 changes: 22 additions & 20 deletions man/last.Rd
Original file line number Diff line number Diff line change
@@ -1,34 +1,36 @@
\name{last}
\alias{first}
\alias{last}
\title{ Last item of an object }
\title{ First/last item of an object }
\description{
Returns the last item of a vector or list, or the last row of a data.frame or
data.table.
Returns the first/last item of a vector or list, or the first/last row of a data.frame
or data.table. The main difference to head/tail is that the default for \code{n} is 1
rather than 6.
}
\usage{
last(x, \dots)
first(x, n=1L, \dots)
last(x, n=1L, \dots)
}
\arguments{
\item{x}{ A vector, list, data.frame or data.table. Otherwise the S3 method of
\code{xts::last} is deployed. }
\item{\dots}{ Not applicable for \code{data.table::last}. Any arguments here are
passed through to \code{xts::last}. }
\item{x}{ A vector, list, data.frame or data.table. Otherwise the S3 method
of \code{xts::first} is deployed. }
\item{n}{ A numeric vector length 1. How many items to select. }
\item{\dots}{ Not applicable for \code{data.table} first/last. Any arguments here
are passed through to \code{xts}'s first/last. }
}
% \details{
% }
\value{
If no other arguments are supplied it depends on the type of x. The last item
of a vector or list. The last row of a \code{data.frame} or \code{data.table}.
Otherwise, whatever \code{xts::last} returns (if package xts has been loaded,
otherwise a helpful error).

If any argument is supplied in addition to \code{x} (such as \code{n} or
\code{keep} in \code{xts::last}), regardless of \code{x}'s type, then
\code{xts::last} is called if xts has been loaded, otherwise a helpful error.
If no other arguments are supplied it depends on the type of \code{x}. The first/last item
of a vector or list. The first/last row of a \code{data.frame} or \code{data.table}.
For other types, or if any argument is supplied in addition to \code{x} (such as \code{n}, or
\code{keep} in \code{xts}) regardless of \code{x}'s type, then \code{xts::first}/
\code{xts::last} is called if \code{xts} has been loaded, otherwise \code{utils::head}/\code{utils::tail}.
}
\seealso{ \code{\link{NROW}}, \code{\link{head}}, \code{\link{tail}},
\code{\link{first}} }
\seealso{ \code{\link{NROW}}, \code{\link{head}}, \code{\link{tail}} }
\examples{
first(1:5) # [1] 1
x = data.table(x=1:5, y=6:10)
first(x) # same as x[1]

last(1:5) # [1] 5
x = data.table(x=1:5, y=6:10)
last(x) # same as x[5]
Expand Down

0 comments on commit 30a4fcd

Please sign in to comment.