Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

adding show() option missingstring to change the string that prints for missing values #1688

Closed
wants to merge 11 commits into from
56 changes: 31 additions & 25 deletions src/abstractdataframe/io.jl
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,11 @@ function html_escape(cell::AbstractString)
return cell
end

Base.show(io::IO, mime::MIME"text/html", df::AbstractDataFrame; summary::Bool=true) =
_show(io, mime, df, summary=summary)
Base.show(io::IO, mime::MIME"text/html", df::AbstractDataFrame; summary::Bool=true, missingstring::AbstractString="missing") =
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you please correctly align the indentation of the code here and in all places below/

_show(io, mime, df, summary=summary, missingstring=missingstring)

function _show(io::IO, ::MIME"text/html", df::AbstractDataFrame;
summary::Bool=true, rowid::Union{Int,Nothing}=nothing)
summary::Bool=true, rowid::Union{Int,Nothing}=nothing, missingstring::AbstractString="missing")
n = size(df, 1)
if rowid !== nothing && n != 1
throw(ArgumentError("rowid may be passed only with a single row data frame"))
Expand Down Expand Up @@ -138,7 +138,11 @@ function _show(io::IO, ::MIME"text/html", df::AbstractDataFrame;
end
for column_name in cnames
if isassigned(df[column_name], row)
cell = sprint(ourshowcompact, df[row, column_name])
if !ismissing(df[row, column_name])
cell = sprint(ourshowcompact, df[row, column_name])
else
cell = sprint(ourshowcompact, missingstring)
end
else
cell = sprint(ourshowcompact, Base.undef_ref_str)
end
Expand All @@ -158,13 +162,13 @@ function _show(io::IO, ::MIME"text/html", df::AbstractDataFrame;
write(io, "</table>")
end

function Base.show(io::IO, mime::MIME"text/html", dfr::DataFrameRow; summary::Bool=true)
function Base.show(io::IO, mime::MIME"text/html", dfr::DataFrameRow; summary::Bool=true, missingstring::AbstractString="missing")
r, c = parentindices(dfr)
write(io, "<p>DataFrameRow</p>")
_show(io, mime, view(parent(dfr), [r], c), summary=summary, rowid=r)
_show(io, mime, view(parent(dfr), [r], c), summary=summary, rowid=r, missingstring=missingstring)
end

function Base.show(io::IO, mime::MIME"text/html", gd::GroupedDataFrame)
function Base.show(io::IO, mime::MIME"text/html", gd::GroupedDataFrame; missingstring::AbstractString="missing")
N = length(gd)
keynames = names(gd.parent)[gd.cols]
parent_names = names(gd.parent)
Expand All @@ -182,7 +186,7 @@ function Base.show(io::IO, mime::MIME"text/html", gd::GroupedDataFrame)
write(io, "<p><i>First Group ($nrows $rows): ")
join(io, identified_groups, ", ")
write(io, "</i></p>")
show(io, mime, gd[1], summary=false)
show(io, mime, gd[1], summary=false, missingstring=missingstring)
end
if N > 1
nrows = size(gd[N], 1)
Expand All @@ -195,7 +199,7 @@ function Base.show(io::IO, mime::MIME"text/html", gd::GroupedDataFrame)
write(io, "<p><i>Last Group ($nrows $rows): ")
join(io, identified_groups, ", ")
write(io, "</i></p>")
show(io, mime, gd[N], summary=false)
show(io, mime, gd[N], summary=false, missingstring=missingstring)
end
end

Expand All @@ -219,10 +223,10 @@ function latex_escape(cell::AbstractString)
replace(cell, ['\\','~','#','$','%','&','_','^','{','}']=>latex_char_escape)
end

Base.show(io::IO, mime::MIME"text/latex", df::AbstractDataFrame) =
_show(io, mime, df)
Base.show(io::IO, mime::MIME"text/latex", df::AbstractDataFrame; missingstring::AbstractString="missing") =
_show(io, mime, df, missingstring=missingstring)

function _show(io::IO, ::MIME"text/latex", df::AbstractDataFrame; rowid=nothing)
function _show(io::IO, ::MIME"text/latex", df::AbstractDataFrame; rowid=nothing, missingstring::AbstractString="missing")
nrows = size(df, 1)
ncols = size(df, 2)

Expand Down Expand Up @@ -265,6 +269,8 @@ function _show(io::IO, ::MIME"text/latex", df::AbstractDataFrame; rowid=nothing)
else
print(io, latex_escape(sprint(ourshowcompact, cell)))
end
else
print(io, latex_escape(sprint(ourshowcompact, missingstring)))
end
end
write(io, " \\\\\n")
Expand All @@ -279,12 +285,12 @@ function _show(io::IO, ::MIME"text/latex", df::AbstractDataFrame; rowid=nothing)
write(io, "\\end{tabular}\n")
end

function Base.show(io::IO, mime::MIME"text/latex", dfr::DataFrameRow)
function Base.show(io::IO, mime::MIME"text/latex", dfr::DataFrameRow; missingstring::AbstractString="missing")
r, c = parentindices(dfr)
_show(io, mime, view(parent(dfr), [r], c), rowid=r)
_show(io, mime, view(parent(dfr), [r], c), rowid=r, missingstring=missingstring)
end

function Base.show(io::IO, mime::MIME"text/latex", gd::GroupedDataFrame)
function Base.show(io::IO, mime::MIME"text/latex", gd::GroupedDataFrame; missingstring::AbstractString="missing")
N = length(gd)
keynames = names(gd.parent)[gd.cols]
parent_names = names(gd.parent)
Expand All @@ -303,7 +309,7 @@ function Base.show(io::IO, mime::MIME"text/latex", gd::GroupedDataFrame)
write(io, "First Group ($nrows $rows): ")
join(io, identified_groups, ", ")
write(io, "\n\n")
show(io, mime, gd[1])
show(io, mime, gd[1], missingstring=missingstring)
end
if N > 1
nrows = size(gd[N], 1)
Expand All @@ -317,7 +323,7 @@ function Base.show(io::IO, mime::MIME"text/latex", gd::GroupedDataFrame)
write(io, "Last Group ($nrows $rows): ")
join(io, identified_groups, ", ")
write(io, "\n\n")
show(io, mime, gd[N])
show(io, mime, gd[N], missingstring=missingstring)
end
end

Expand All @@ -327,22 +333,22 @@ end
#
##############################################################################

function Base.show(io::IO, mime::MIME"text/csv", dfr::DataFrameRow)
function Base.show(io::IO, mime::MIME"text/csv", dfr::DataFrameRow; missingstring::AbstractString="missing")
r, c = parentindices(dfr)
show(io, mime, view(parent(dfr), [r], c))
show(io, mime, view(parent(dfr), [r], c), missingstring=missingstring)
end

function Base.show(io::IO, mime::MIME"text/tab-separated-values", dfr::DataFrameRow)
function Base.show(io::IO, mime::MIME"text/tab-separated-values", dfr::DataFrameRow; missingstring::AbstractString="missing")
r, c = parentindices(dfr)
show(io, mime, view(parent(dfr), [r], c))
show(io, mime, view(parent(dfr), [r], c), missingstring=missingstring)
end

function Base.show(io::IO, ::MIME"text/csv", df::AbstractDataFrame)
printtable(io, df, header = true, separator = ',')
function Base.show(io::IO, ::MIME"text/csv", df::AbstractDataFrame; missingstring::AbstractString="missing")
printtable(io, df, header = true, separator = ',', missingstring=missingstring)
end

function Base.show(io::IO, ::MIME"text/tab-separated-values", df::AbstractDataFrame)
printtable(io, df, header = true, separator = '\t')
function Base.show(io::IO, ::MIME"text/tab-separated-values", df::AbstractDataFrame; missingstring::AbstractString="missing")
printtable(io, df, header = true, separator = '\t', missingstring=missingstring)
end

##############################################################################
Expand Down
40 changes: 30 additions & 10 deletions src/abstractdataframe/show.jl
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ end
DataFrames.getmaxwidths(df::AbstractDataFrame,
rowindices1::AbstractVector{Int},
rowindices2::AbstractVector{Int},
rowlabel::Symbol)
rowlabel::Symbol,
missingstring::AbstractString)

Calculate, for each column of an AbstractDataFrame, the maximum
string width used to render the name of that column, its type, and the
Expand All @@ -78,6 +79,7 @@ implicit row ID column contained in every `AbstractDataFrame`.
- `rowlabel::AbstractString`: The label that will be used when rendered the
numeric ID's of each row. Typically, this will be set to "Row".

- `missingstring::AbstractString = "missing"`: The string that is printed for `missing` values.
# Examples
```jldoctest
julia> using DataFrames
Expand All @@ -95,10 +97,12 @@ function getmaxwidths(df::AbstractDataFrame,
rowindices1::AbstractVector{Int},
rowindices2::AbstractVector{Int},
rowlabel::Symbol,
missingstring::AbstractString,
rowid=nothing) # -> Vector{Int}
maxwidths = Vector{Int}(undef, size(df, 2) + 1)

undefstrwidth = ourstrwidth(Base.undef_ref_str)
missingstrwidth = ourstrwidth(missingstring)

j = 1
for (name, col) in eachcol(df, true)
Expand All @@ -108,7 +112,11 @@ function getmaxwidths(df::AbstractDataFrame,
# (2) Consider length of longest entry in that column
for indices in (rowindices1, rowindices2), i in indices
if isassigned(col, i)
maxwidth = max(maxwidth, ourstrwidth(col[i]))
if ismissing(col[i])
maxwidth = max(maxwidth, missingstrwidth)
else
maxwidth = max(maxwidth, ourstrwidth(col[i]))
end
else
maxwidth = max(maxwidth, undefstrwidth)
end
Expand Down Expand Up @@ -148,7 +156,7 @@ julia> using DataFrames

julia> df = DataFrame(A = 1:3, B = ["x", "yy", "z"]);

julia> maxwidths = DataFrames.getmaxwidths(df, 1:1, 3:3, :Row)
julia> maxwidths = DataFrames.getmaxwidths(df, 1:1, 3:3, :Row, "missing")
3-element Array{Int64,1}:
1
1
Expand Down Expand Up @@ -197,7 +205,7 @@ julia> using DataFrames

julia> df = DataFrame(A = 1:3, B = ["x", "yy", "z"]);

julia> maxwidths = DataFrames.getmaxwidths(df, 1:1, 3:3, :Row)
julia> maxwidths = DataFrames.getmaxwidths(df, 1:1, 3:3, :Row, "missing")
3-element Array{Int64,1}:
1
1
Expand Down Expand Up @@ -257,6 +265,7 @@ required for printing have been precomputed.
required to render each column.
- `leftcol::Int`: The index of the first column in a chunk to be rendered.
- `rightcol::Int`: The index of the last column in a chunk to be rendered.
- `missingstring::AbstractString = "missing"`: The string that is printed for `missing` values.
- `rowid`: Used to handle showing `DataFrameRow`.

# Examples
Expand All @@ -276,6 +285,7 @@ function showrowindices(io::IO,
maxwidths::Vector{Int},
leftcol::Int,
rightcol::Int,
missingstring::AbstractString,
rowid) # -> Void
rowmaxwidth = maxwidths[end]

Expand All @@ -298,7 +308,8 @@ function showrowindices(io::IO,
s = df[i, j]
strlen = ourstrwidth(s)
if ismissing(s)
printstyled(io, s, color=:light_black)
printstyled(io, missingstring, color=:light_black)
strlen = ourstrwidth(missingstring)
elseif s === nothing
strlen = 0
else
Expand Down Expand Up @@ -363,6 +374,7 @@ NOTE: The value of `maxwidths[end]` must be the string width of
- `displaysummary::Bool`: Should a brief string summary of the
AbstractDataFrame be rendered to the I/O stream before printing the
contents of the renderable rows? Defaults to `true`.
- `missingstring::AbstractString = "missing"`: The string that is printed for `missing` values.
- `rowid = nothing`: Used to handle showing `DataFrameRow`

# Examples
Expand Down Expand Up @@ -390,6 +402,7 @@ function showrows(io::IO,
allcols::Bool = false,
rowlabel::Symbol = :Row,
displaysummary::Bool = true,
missingstring::AbstractString = "missing",
rowid=nothing) # -> Void
ncols = size(df, 2)

Expand Down Expand Up @@ -481,6 +494,7 @@ function showrows(io::IO,
maxwidths,
leftcol,
rightcol,
missingstring,
rowid)

if !isempty(rowindices2)
Expand All @@ -491,6 +505,7 @@ function showrows(io::IO,
maxwidths,
leftcol,
rightcol,
missingstring,
rowid)
end

Expand All @@ -510,6 +525,7 @@ function _show(io::IO,
splitcols = get(io, :limit, false),
rowlabel::Symbol = :Row,
summary::Bool = true,
missingstring::AbstractString = "missing",
rowid=nothing)
nrows = size(df, 1)
if rowid !== nothing
Expand All @@ -526,7 +542,7 @@ function _show(io::IO,
rowindices1 = 1:bound
rowindices2 = max(bound + 1, nrows - nrowssubset + 1):nrows
end
maxwidths = getmaxwidths(df, rowindices1, rowindices2, rowlabel, rowid)
maxwidths = getmaxwidths(df, rowindices1, rowindices2, rowlabel, missingstring, rowid)
width = getprintedwidth(maxwidths)
showrows(io,
df,
Expand All @@ -537,6 +553,7 @@ function _show(io::IO,
allcols,
rowlabel,
summary,
missingstring,
rowid)
return
end
Expand Down Expand Up @@ -575,6 +592,7 @@ while `splitcols` defaults to `true`.
By default this is the case only if `io` has the `IOContext` property `limit` set.
- `rowlabel::Symbol = :Row`: The label to use for the column containing row numbers.
- `summary::Bool = true`: Whether to print a brief string summary of the data frame.
- `missingstring::AbstractString = "missing"`: The string that is printed for `missing` values.

# Examples
```jldoctest
Expand All @@ -598,16 +616,18 @@ Base.show(io::IO,
allcols::Bool = !get(io, :limit, false),
splitcols = get(io, :limit, false),
rowlabel::Symbol = :Row,
summary::Bool = true) =
summary::Bool = true,
missingstring::AbstractString = "missing") =
_show(io, df, allrows=allrows, allcols=allcols, splitcols=splitcols,
rowlabel=rowlabel, summary=summary)
rowlabel=rowlabel, summary=summary, missingstring=missingstring)

Base.show(df::AbstractDataFrame;
allrows::Bool = !get(stdout, :limit, true),
allcols::Bool = !get(stdout, :limit, true),
splitcols = get(stdout, :limit, true),
rowlabel::Symbol = :Row,
summary::Bool = true) =
summary::Bool = true,
missingstring::AbstractString = "missing") =
show(stdout, df,
allrows=allrows, allcols=allcols, splitcols=splitcols,
rowlabel=rowlabel, summary=summary)
rowlabel=rowlabel, summary=summary, missingstring=missingstring)
10 changes: 6 additions & 4 deletions src/dataframerow/show.jl
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
function Base.show(io::IO, dfr::DataFrameRow;
allcols::Bool = !get(io, :limit, false),
splitcols = get(io, :limit, false),
rowlabel::Symbol = :Row)
rowlabel::Symbol = :Row,
missingstring::AbstractString = "missing")
r, c = parentindices(dfr)
print(io, "DataFrameRow")
_show(io, view(parent(dfr), [r], c), allcols=allcols, splitcols=splitcols,
rowlabel=rowlabel, summary=false, rowid=r)
rowlabel=rowlabel, summary=false, missingstring=missingstring, rowid=r)
end

Base.show(dfr::DataFrameRow;
allcols::Bool = !get(io, :limit, true),
splitcols = get(io, :limit, true),
rowlabel::Symbol = :Row) =
show(stdout, dfr, allcols=allcols, splitcols=splitcols, rowlabel=rowlabel)
rowlabel::Symbol = :Row,
missingstring::AbstractString = "missing") =
show(stdout, dfr, allcols=allcols, splitcols=splitcols, rowlabel=rowlabel, missingstring=missingstring)
14 changes: 8 additions & 6 deletions src/groupeddataframe/show.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ function Base.show(io::IO, gd::GroupedDataFrame;
allcols::Bool = !get(io, :limit, false),
splitcols::Bool = get(io, :limit, false),
rowlabel::Symbol = :Row,
summary::Bool = true)
summary::Bool = true,
missingstring::AbstractString = "missing")
N = length(gd)
keynames = names(gd.parent)[gd.cols]
parent_names = names(gd.parent)
Expand All @@ -25,7 +26,7 @@ function Base.show(io::IO, gd::GroupedDataFrame;
join(io, identified_groups, ", ")

show(io, gd[i], summary=false,
allrows=allrows, allcols=allcols, rowlabel=rowlabel)
allrows=allrows, allcols=allcols, rowlabel=rowlabel, missingstring=missingstring)
end
else
if N > 0
Expand All @@ -39,7 +40,7 @@ function Base.show(io::IO, gd::GroupedDataFrame;
join(io, identified_groups, ", ")

show(io, gd[1], summary=false,
allrows=allrows, allcols=allcols, rowlabel=rowlabel)
allrows=allrows, allcols=allcols, rowlabel=rowlabel, missingstring=missingstring)
end
if N > 1
nrows = size(gd[N], 1)
Expand All @@ -52,7 +53,7 @@ function Base.show(io::IO, gd::GroupedDataFrame;
join(io, identified_groups, ", ")

show(io, gd[N], summary=false,
allrows=allrows, allcols=allcols, rowlabel=rowlabel)
allrows=allrows, allcols=allcols, rowlabel=rowlabel, missingstring=missingstring)
end
end
end
Expand All @@ -63,8 +64,9 @@ function Base.show(df::GroupedDataFrame;
allgroups::Bool = !get(stdout, :limit, true),
splitcols::Bool = get(stdout, :limit, true),
rowlabel::Symbol = :Row,
summary::Bool = true) # -> Nothing
summary::Bool = true,
missingstring::String = "missing") # -> Nothing
return show(stdout, df,
allrows=allrows, allcols=allcols, allgroups=allgroups, splitcols=splitcols,
rowlabel=rowlabel, summary=summary)
rowlabel=rowlabel, summary=summary, missingstring=missingstring)
end
Loading