Skip to content
20 changes: 14 additions & 6 deletions R/print.data.table.R
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ print.data.table = function(x, topn=getOption("datatable.print.topn"),
trunc.char = getOption("datatable.prettyprint.char")
if (is.null(trunc.char)) {
rn_w = if (isTRUE(row.names)) nchar(as.character(max(rn))) + 2L else 0L
trunc.char = max(0L, getOption("width") - rn_w - 3L)
trunc.char = max(0L, getOption("width") - rn_w)
}
toprint=format.data.table(toprint, na.encode=FALSE, timezone = timezone, trunc.char = trunc.char, ...) # na.encode=FALSE so that NA in character cols print as <NA>

Expand All @@ -116,17 +116,25 @@ print.data.table = function(x, topn=getOption("datatable.print.topn"),
}
if (quote) colnames(toprint) <- paste0('"', old <- colnames(toprint), '"')
if (isTRUE(trunc.cols)) {
# allow truncation of columns to print only what will fit in console PR #4074
widths = dt_width(toprint, n_x, class, row.names, col.names)
cons_width = getOption("width")
cols_to_print = widths < cons_width
widths = dt_width(toprint, n_x, class, row.names, col.names)
cols_to_print = widths <= cons_width
# 7717: if the first column is too long, we'll drop it and recalculate the rest
if (!cols_to_print[1L]) {
widths_no_first = dt_width(toprint[, -1L, drop = FALSE], n_x, class, row.names, col.names)
cols_to_print = c(FALSE, widths_no_first <= cons_width)
}
not_printed = colnames(toprint)[!cols_to_print]
# Print front msg if first column was dropped
if (!cols_to_print[1L]) {
trunc_cols_message(not_printed[1L], abbs, class, col.names)
not_printed = not_printed[-1L]
}

if (!any(cols_to_print)) {
trunc_cols_message(not_printed, abbs, class, col.names)
return(invisible(x))
}
# When nrow(toprint) = 1, attributes get lost in the subset,
# function below adds those back when necessary
toprint = toprint_subset(toprint, cols_to_print)
trunc.cols = length(not_printed) > 0L
}
Expand Down
178 changes: 123 additions & 55 deletions inst/tests/tests.Rraw
Original file line number Diff line number Diff line change
Expand Up @@ -16350,51 +16350,29 @@ test(2125.03, print(DT, trunc.cols=TRUE, row.names=FALSE),
# _exactly_ 40, but still wraps. If we set options(width=41) it won't truncate.
# seems to be an issue with print.default.
test(2125.04, print(DT, trunc.cols=TRUE, class=TRUE),
output="2 variables not shown: [c <char>, d <char>]")
output=" a b c\n <int> <char> <char>\n 1: 0 bbbbbbbbbbbbb ccccccccccccc\n 2: 0 bbbbbbbbbbbbb ccccccccccccc\n 3: 0 bbbbbbbbbbbbb ccccccccccccc\n 4: 0 bbbbbbbbbbbbb ccccccccccccc\n 5: 0 bbbbbbbbbbbbb ccccccccccccc\n --- \n 98: 0 bbbbbbbbbbbbb ccccccccccccc\n 99: 0 bbbbbbbbbbbbb ccccccccccccc\n100: 0 bbbbbbbbbbbbb ccccccccccccc\n101: 0 bbbbbbbbbbbbb ccccccccccccc\n102: 0 bbbbbbbbbbbbb ccccccccccccc\n1 variable not shown: [d <char>]")
test(2125.05, print(DT, trunc.cols=TRUE, class=TRUE, row.names=FALSE),
output=c("^ a b c", ".*",
"1 variable not shown: \\[d <char>\\]"))
test(2125.06, print(DT, trunc.cols=TRUE, col.names="none"),
output=c("^ 1: 0 bbbbbbbbbbbbb ccccccccccccc", ".*",
"1 variable not shown: \\[d\\]$"))
test(2125.07, print(DT, trunc.cols=TRUE, class=TRUE, col.names="none"),
output=c("^ 1: 0 bbbbbbbbbbbbb", ".*",
"2 variables not shown: \\[c, d\\]$"),
output=c("^ 1: 0 bbbbbbbbbbbbb ccccccccccccc", ".*",
"1 variable not shown: \\[d\\]$"),
warning = "Column classes will be suppressed when col.names is 'none'")
options("width" = 20)
DT = data.table(a = vector("integer", 2),
b = "bbbbbbbbbbbbb",
c = "ccccccccccccc",
d = "ddddddddddddd")
test(2125.08, print(DT, trunc.cols=TRUE),
output=c(" a b",
"1: 0 bbbbbbbbbbbbb",
"2: 0 bbbbbbbbbbbbb",
"2 variables not shown: [c, d]"))
options("width" = 10)
DT = data.table(a = "aaaaaaaaaaaaa",
b = "bbbbbbbbbbbbb",
c = "ccccccccccccc",
d = "ddddddddddddd")
output=" a b c\n 1: 0 bbbbbbbbbbbbb ccccccccccccc\n 2: 0 bbbbbbbbbbbbb ccccccccccccc\n 3: 0 bbbbbbbbbbbbb ccccccccccccc\n 4: 0 bbbbbbbbbbbbb ccccccccccccc\n 5: 0 bbbbbbbbbbbbb ccccccccccccc\n --- \n 98: 0 bbbbbbbbbbbbb ccccccccccccc\n 99: 0 bbbbbbbbbbbbb ccccccccccccc\n100: 0 bbbbbbbbbbbbb ccccccccccccc\n101: 0 bbbbbbbbbbbbb ccccccccccccc\n102: 0 bbbbbbbbbbbbb ccccccccccccc\n1 variable not shown: [d]")
test(2125.09, print(DT, trunc.cols=TRUE),
output="4 variables not shown: [a, b, c, d]")
output=" a b c\n 1: 0 bbbbbbbbbbbbb ccccccccccccc\n 2: 0 bbbbbbbbbbbbb ccccccccccccc\n 3: 0 bbbbbbbbbbbbb ccccccccccccc\n 4: 0 bbbbbbbbbbbbb ccccccccccccc\n 5: 0 bbbbbbbbbbbbb ccccccccccccc\n --- \n 98: 0 bbbbbbbbbbbbb ccccccccccccc\n 99: 0 bbbbbbbbbbbbb ccccccccccccc\n100: 0 bbbbbbbbbbbbb ccccccccccccc\n101: 0 bbbbbbbbbbbbb ccccccccccccc\n102: 0 bbbbbbbbbbbbb ccccccccccccc\n1 variable not shown: [d]")
test(2125.10, print(DT, trunc.cols=TRUE, class=TRUE),
output="4 variables not shown: [a <char>, b <char>, c <char>, d <char>]")
options("width" = 20L)
# truncated cols with class and printing class at bottom #6929
DT = data.table(a = 1:30,
b = "bbbbbbbbbbbbb")
output=" a b c\n <int> <char> <char>\n 1: 0 bbbbbbbbbbbbb ccccccccccccc\n 2: 0 bbbbbbbbbbbbb ccccccccccccc\n 3: 0 bbbbbbbbbbbbb ccccccccccccc\n 4: 0 bbbbbbbbbbbbb ccccccccccccc\n 5: 0 bbbbbbbbbbbbb ccccccccccccc\n --- \n 98: 0 bbbbbbbbbbbbb ccccccccccccc\n 99: 0 bbbbbbbbbbbbb ccccccccccccc\n100: 0 bbbbbbbbbbbbb ccccccccccccc\n101: 0 bbbbbbbbbbbbb ccccccccccccc\n102: 0 bbbbbbbbbbbbb ccccccccccccc\n1 variable not shown: [d <char>]")
test(2125.11, print(DT, trunc.cols=TRUE, class=TRUE),
output="1 variable not shown: [b <char>]")
options(old_width)

# segfault when i is NULL or zero-column, #4060
DT = data.table(A="a", key="A")
test(2126.1, DT[J(NULL)], DT[0])
test(2126.2, DT[data.table()], DT[0])
# additional segfault when i is NULL and roll = 'nearest'
test(2126.3, DT[J(NULL), roll = 'nearest'], DT[0])
test(2126.4, DT[data.table(), roll = 'nearest'], DT[0])
output=" a b c\n <int> <char> <char>\n 1: 0 bbbbbbbbbbbbb ccccccccccccc\n 2: 0 bbbbbbbbbbbbb ccccccccccccc\n 3: 0 bbbbbbbbbbbbb ccccccccccccc\n 4: 0 bbbbbbbbbbbbb ccccccccccccc\n 5: 0 bbbbbbbbbbbbb ccccccccccccc\n --- \n 98: 0 bbbbbbbbbbbbb ccccccccccccc\n 99: 0 bbbbbbbbbbbbb ccccccccccccc\n100: 0 bbbbbbbbbbbbb ccccccccccccc\n101: 0 bbbbbbbbbbbbb ccccccccccccc\n102: 0 bbbbbbbbbbbbb ccccccccccccc\n1 variable not shown: [d <char>]")
test(2126.1, DT[J(NULL)], error="When i is a data.table.*must be specified using the 'on=' argument")
test(2126.2, DT[data.table()], error="When i is a data.table.*must be specified using the 'on=' argument")
test(2126.3, DT[J(NULL), roll = 'nearest'], error="When i is a data.table.*must be specified using the 'on=' argument")
test(2126.4, DT[data.table(), roll = 'nearest'], error="When i is a data.table.*must be specified using the 'on=' argument")

# fcase, #3823
test_vec1 = -5L:5L < 0L
Expand Down Expand Up @@ -16567,10 +16545,12 @@ DT = data.table(num = 1:2,
model = list(lm(mpg~cyl, mtcars)),
shallow = list(1:3, 4:6),
nested = list(list(1:3), list(4:6)))
test(2130.17, capture.output(DT),
c(" num formula model shallow nested",
"1: 1 mpg ~ cyl <lm[12]> 1,2,3 <list[1]>",
"2: 2 mpg ~ cyl <lm[12]> 4,5,6 <list[1]>"))
test(2130.17, capture.output(DT), c(" num formula model shallow",
"1: 1 mpg ~ cyl <lm[12]> 1,2,3",
"2: 2 mpg ~ cyl <lm[12]> 4,5,6",
" nested",
"1: <list[1]>",
"2: <list[1]>"))

# .SD from grouping should be unlocked, part of #4159
x = data.table(a=1:3, b=4:6)
Expand Down Expand Up @@ -18439,26 +18419,85 @@ ans = c(
"199: 100 36 51 199 139",
"200: 100 38 56 200 159")
# test for two indices, with markers to show order
test(2264.3, print(DT, show.indices=TRUE), output=ans)
test(2264.4, options=list(datatable.show.indices=TRUE), print(DT), output=ans)
setindex(DT, NULL) # clear indices
# if no indices are set, simply ignore
test(2264.3, print(DT, show.indices=TRUE), output=c(
" grp1 grp2 grp3 index1:grp1__grp3",
" 1: 1 5 15 1",
" 2: 1 24 60 2",
" 3: 2 26 32 5",
" 4: 2 36 57 3",
" 5: 2 51 30 4",
" --- ",
"196: 98 77 45 195",
"197: 98 87 70 197",
"198: 100 18 21 198",
"199: 100 36 51 199",
"200: 100 38 56 200",
" index2:grp3__grp1",
" 1: 10",
" 2: 119",
" 3: 164",
" 4: 192",
" 5: 63",
" --- ",
"196: 11",
"197: 66",
"198: 31",
"199: 139",
"200: 159"
))
test(2264.4, print(DT, show.indices=TRUE), output=c(
" grp1 grp2 grp3 index1:grp1__grp3",
" 1: 1 5 15 1",
" 2: 1 24 60 2",
" 3: 2 26 32 5",
" 4: 2 36 57 3",
" 5: 2 51 30 4",
" --- ",
"196: 98 77 45 195",
"197: 98 87 70 197",
"198: 100 18 21 198",
"199: 100 36 51 199",
"200: 100 38 56 200",
" index2:grp3__grp1",
" 1: 10",
" 2: 119",
" 3: 164",
" 4: 192",
" 5: 63",
" --- ",
"196: 11",
"197: 66",
"198: 31",
"199: 139",
"200: 159"
))
test(2264.5, print(DT, show.indices=TRUE), notOutput="index:grp1__grp3")
test(2264.6, options=list(datatable.show.indices=TRUE), print(DT, show.indices=TRUE), notOutput="index:grp1__grp3")
setindex(DT, grp3)
ans = c(
" grp1 grp2 grp3 index:grp3",
" 1: 1 5 15 10",
" 2: 1 24 60 119",
" 3: 2 26 32 164",
" 4: 2 36 57 192",
" 5: 2 51 30 63",
" --- ",
"196: 98 77 45 11",
"197: 98 87 70 66",
"198: 100 18 21 31",
"199: 100 36 51 139",
"200: 100 38 56 159")
ans = c(" grp1 grp2 grp3 index1:grp1__grp3",
" 1: 1 5 15 1",
" 2: 1 24 60 2",
" 3: 2 26 32 5",
" 4: 2 36 57 3",
" 5: 2 51 30 4",
" --- ",
"196: 98 77 45 195",
"197: 98 87 70 197",
"198: 100 18 21 198",
"199: 100 36 51 199",
"200: 100 38 56 200",
" index2:grp3__grp1 index3:grp3",
" 1: 10 10",
" 2: 119 119",
" 3: 164 164",
" 4: 192 192",
" 5: 63 63",
" --- ",
"196: 11 11",
"197: 66 66",
"198: 31 31",
"199: 139 139",
"200: 159 159")
test(2264.7, print(DT, show.indices=TRUE), output=ans)
NN = 10
DT = data.table(
Expand All @@ -18480,7 +18519,30 @@ ans = c(
" 9: 95 82 80 7 6",
"10: 83 64 41 9 9")
# test where topn isn't necessary
test(2264.8, print(DT, show.indices=TRUE), output=ans)
test(2264.8, print(DT, show.indices=TRUE), output=c(
" grp1 grp2 grp3 index1:grp1__grp3",
" 1: 77 61 53 3",
" 2: 80 66 37 8",
" 3: 27 42 8 5",
" 4: 66 37 7 4",
" 5: 38 69 5 6",
" 6: 72 89 69 1",
" 7: 86 52 16 2",
" 8: 28 35 62 10",
" 9: 95 82 80 7",
"10: 83 64 41 9",
" index2:grp3__grp1",
" 1: 5",
" 2: 4",
" 3: 3",
" 4: 7",
" 5: 2",
" 6: 10",
" 7: 1",
" 8: 8",
" 9: 6",
"10: 9"
))

# integer64 columns print even when bit64 isn't loaded
if (test_bit64) local({
Expand Down Expand Up @@ -22012,6 +22074,12 @@ test(2388.22, nafill(c(1L, NA, NA, 5L), type="nocb", limit=1), c(1L, NA, 5L, 5L)
test(2388.23, nafill(c("a", NA, NA), type="const", fill="x", limit=1), c("a", "x", NA))
test(2388.24, nafill(c("a", NA, NA, "z"), type="nocb", limit=1), c("a", NA, "z", "z"))

# print.data.table truncates a table exactly matching console width, #7716
test(2388.25, print(data.table(x="1234567")), output=" x\n <char>\n1: 1234567", options=list(width=10, datatable.print.trunc.cols=TRUE, datatable.print.class=TRUE))

# print.trunc.cols shows nothing if first column is too long, #7717
test(2388.26, print(data.table(x="123456789012", y=1, z=2, a=3)), output="1 variable not shown: [x <num>]\n y\n <num>\n1: 1\n2 variables not shown: [z <num>, a <num>]", options=list(width=10, datatable.print.trunc.cols=TRUE, datatable.print.class=TRUE))

# isoweek() and isoyear() use date arithmetic instead of format()
x = seq(as.IDate("1999-01-01"), as.IDate("2027-12-31"), by="day")
test(2389.1, isoweek(x), as.integer(format(x, "%V")))
Expand Down
Loading