-
rowGroupMeans()
- Fixed regression when using custom
rowStatsFunc
, added test cases to confirm. - Fixed regression when using
base::rowMeans()
whenmatrixStats
is available, since it no longer exists in that package. - Fixed regression by not passing
...
torowStatsFunc
, instead it only passesna.rm
. Added test case to confirm.
- Fixed regression when using custom
-
rowGroupMeans()
androwRmMadOutliers()
- New argument
includeAttributes=FALSE
turns off default attributes with number of replicates, but can be re-enabled when needed. - Both functions now also support SparseMatrix objects from Matrix,
which helps when using
Seurat
andSingleCellExperiment
objects. - Both functions will use
matrixStats
,sparseMatrixStats
, orbase
R summary functions based upon the object type and installed packages. - Added tests for both function to cover the basics.
- New argument
-
Updated all tests to remove deprecated
testthat::context()
.
-
readOpenxlsx()
- Bug was caused when using
startRow
androws
causing the column headers to use therows[startRow]
which was not as intended. The logic is now to userows
when present, orstartRow
otherwise, never both. The help docs now describe this distinction. The same logic is applied tocols
andstartCol
.
- Bug was caused when using
-
kable_coloring()
- It was not properly enforcing HTML output, causing HTML tags to appear as HTML tags, and not colorize the text for example.
- Added test coverage for this scenario.
-
plotRidges()
now works properly with single vector, single column, and any input withoutrownames()
orcolnames()
. -
plotPolygonDensity()
now properly reverts any changes topar()
, such as"mfrow"
and axis settings"xaxs"
and"yaxs"
.
-
mmixedOrder()
- Fixed mis-placed parentheses in conditional statement, affecting only
factor
columns. Apparently introduced with0.0.100.900
below.
- Fixed mis-placed parentheses in conditional statement, affecting only
-
mmixedOrder()
,mixedSortDF()
- fixed error when sorting class
"Date"
,"POSIXct"
, or"POSIXt"
. Previous these columns either caused an error, or were not sorted. Now these columns are handled asnumeric
columns, and are converted usingas.numeric()
. Further, the actual error arose from converting alist
todata.frame
which failed for class"octmode"
. This step is avoided, sincemmixedOrder()
operates the same withlist
input anyway. An example is added tomixedSortDF()
using output fromfile.info()
.
- fixed error when sorting class
-
heatmap_row_order()
,heatmap_column_order()
- new argument
which_heatmap
which allows for returning the row or column order of a specific heatmap, whenHeatmapList
is provided. It works with horizontal side-by-side heatmap orientation, and vertical top-over-bottom heatmap orientation.
- new argument
-
breaksByVector()
- Fixed order of
class(x)
to beany(X %in% class(x))
.
- Fixed order of
-
rgb2col()
- Minor change when detecting
class(red)
to reverse the order to"RGB" %in% class(red)
in casered
has multiple classes.
- Minor change when detecting
-
pasteByRowOrdered()
- Minor change to allow columns to have multiple classes, so
they are handled accordingly. Should only affect when
keepOrder=TRUE
, which checks for presence of"character"
columns.
- Minor change to allow columns to have multiple classes, so
they are handled accordingly. Should only affect when
-
writeOpenxlsx()
,applyXlsxCategoricalColor()
- Fixed bug which caused categorical colors to be applied out of sync
with columns in the
data.frame
, when called viawriteOpenxlsx()
. It was caused by using the optioncolRange
to apply the categorical colors to a subset of data, providing substantial speed but at the expense of columns becoming out of sync for columns which were not continuously categorically colored starting at column 1. The bug is fixed.
- Fixed bug which caused categorical colors to be applied out of sync
with columns in the
-
printDebug()
- removed erroneous additional newline
"<br/>"
withhtmlOut=TRUE
- new arg default
comment=!htmlOut
sohtmlOut=TRUE
by default turns off the comment prefix. Usually HTML output is for RMarkdown, where the comment prefix causes the text to become a heading, where the RMarkdown chunk option usesresults='asis'
.
- removed erroneous additional newline
-
printDebugHtml()
- simple wrapper to
printDebug()
intended for HTML output, using optionshtmlOut=TRUE
andcomment=FALSE
specifically for RMarkdown output using chunk optionresults='asis'
.
- simple wrapper to
-
More functions were updated for CRAN compliance, removing
:::
, including@examples
and@returns
. -
printDebug()
- more arguments use
options()
for potential overrides - removed errant argument
x
which was ignored anyway
- more arguments use
The main update enables colorSub
input as list
for several functions:
writeOpenxlsx()
, kable_coloring()
, and applyXlsxCategoricalFormat()
.
This feature enables passing a color function, or color assignments
that are specific to each column in the data.
The companion function platjam::design2colors()
takes a data.frame
and returns a list
of colors or color functions, one per column,
suitable for use directly in the functions updated above.
The design2colors()
function will likely move into colorjam
.
-
applyXlsxCategoricalFormat()
- argument
colorSub
now accepts a colorlist
named by colnames, with either namedcharacter
vector of colors for each column, or afunction
that takes column values and returnscharacter
colors for each value. - the method for matching
names(colorSub)
to cell values is slightly updated, mainly affecting color assignments forcharacter
strings that contain whitespace and punctuation characters.
- argument
-
writeOpenxlsx()
- argument
colorSub
now accepts eithercharacter
input as previously required, or now acceptslist
input named bycolnames(x)
whose list elements are eithercharacter
vector of colors, or colorfunction
. - Some internal processing is slightly altered to accomodate the change,
applyXlsxCategoricalFormat()
is called with one extra row to include the colnames, but it should be equivalent to previous behavior otherwise. - The change means that value
"A"
can be colored red in one column, while"A"
can be colored blue in another column. It also means that numeric columns can each have their own custom color function, which means it can exactly match a heatmap color function for example, instead of relying upon the limited conditional formatting available in MS Excel.
- argument
-
kable_coloring()
-
moved to its own R file for convenience
-
removed dependency on dplyr
-
changed
require()
tocheck_pkg_available()
to avoid attaching thekableExtra
package. -
argument
colorSub
now accepts three types of input:character
vector of colors named by column valuesfunction
that takes column values and returns colorslist
named bycolnames(df)
, defining columns in each column usingcharacter
orfunction
as described above.
-
colorSub
aslist
input enables colorizingnumeric
columns by passing a color function:circlize::colorRamp2(colors=x, breaks=y)
-
new argument
align
to apply alignment per column, and retains proper alignment for numeric columns which are colorized (something kableExtra does not do by default). -
new argument
format.args
fornumeric
column formatting by default, and is maintained even whennumeric
columns are colorized (which is also not handled by kableExtra by default). -
new argument
border_left
,border_right
which by default show a light grey left border per column -
new argument
extra_css
which by default turns off word-wrap per column -
new argument
row.names
passed tokableExtra::kable()
but repeated to help determine the number of columns used for the left border.
-
-
unalpha()
- new argument
keepNA=FALSE
which allowsNA
conversion to"#FFFFFF"
bygrDevices::col2rgb()
; with new optionkeepNA=TRUE
which returnsNA
.
- new argument
-
shadowText_options()
- intended to help manage shadowText settings which are stored
as
options()
.
- intended to help manage shadowText settings which are stored
as
-
groupedAxis()
- now returns invisible
data.frame
with relevant coordinates. - new argument
do_plot=TRUE
to allow for suppressing the plot output and handling only the numeric values directly. - Added unit tests.
- now returns invisible
minorLogTicks()
resolved warnings.minorLogTicksAxis()
resolved warnings.shadowText()
resolved warnings.showColors()
resolved warnings in the examples.rbindList()
removed base R example that produced a warning.plotSmoothScatter()
removed warnings.
-
plotSmoothScatter()
- Fixed regression where it was printing lots of verbose info.
-
getColorRamp()
- New argument
dex
as replacement forgradientWtFactor
, reflecting the same argument incolor2gradient()
. This argument is only used when a single color is provided, in order to create a color gradient using that color. The argumentdex
improves the color tone, which more closely matches the original color without becoming too de-saturated during the process. - Change to existing argument:
gradientWtFactor=NULL
so this argument is ignored, in favor of new argumentdex=1
. - Updated unit tests accordingly.
- New argument
-
color2gradient()
- argument
dex
now accepts values at or below zero, by converting them to fractions. - Added unit tests.
- argument
grepls()
now properly works with regular expressions when searching alist
of package functions. Also added unit tests to confirm this use case.- Fixed test cases for
cPaste()
andmixedSort()
functions. getColorRamp()
fixed rare edge case with a named palette, using n=NULL (so it returns a color function), and the palette was reversed.
-
gsubs()
- This function is being moved from
multienrichjam::gsubs()
into jamba. During the process, it was noted that inputx
could not be alist
, which is inconsistent with other functions such aslengths()
. It now processeslist
input either iteratively (if input is a nested list), or as unlisted subsets for optimal performance.
- This function is being moved from
-
plotSmoothScatter()
- New argument
asp
with optional ability to define a fixed aspect ratio. When enabled, the plotxlim
andylim
behaves slightly differently, but consistent withplot()
,plot.default()
, andplot.window()
, which include at leastxlim
andylim
but expand one axis if needed in order to obtain the fixed aspect ratio. - When
add=TRUE
thexlim
andylim
values by default will use the plot device range, instead of the data value range. This change makes the density consistently calculated for the plot area used for display. - The method for drawing background fill color
fillBackground=TRUE
changed from usingusrPar()
to usinggrid::grid.rect()
. However,grid::grid.rect()
apparently honors the plot device itself only whenpar("xpd"=FALSE)
and afterabline()
is called with non-empty and non-infinite value forh
orv
. Weird. Nonetheless, it causesgrid::grid.rect()
to crop output to the plot device, which has the benefit of resizing to the plot device whenasp
aspect ratio is defined, when the device is resized. NormallyusrBox()
draws a box with fixed coordinates, and withasp
is defined thexlim
andylim
will change with the plot device is resized. In future, if thegrid::grid.rect()
method is problematic, the method will need to revert back to usingusrPar()
.
- New argument
-
showColors()
- error was thrown when trying to display
circlize::colorRamp2()
color function, a recently updated version ofcirclize
now stores colors internally as R hex colors, instead of previous versions which storednumeric
matrix of r,g,b color values. - The function was updated to detect whether colors defined for color
breaks in
circlize::colorRamp2()
data arenumeric
matrix of r,g,b values, orcharacter
vector of R colors. It should therefore be robust to earlier or newer versions ofcirclize:: colorRamp2()
color functions.
- error was thrown when trying to display
-
showColors()
- new argument
doPlot=TRUE
which allows disabling the graphical output, mainly motivated by the desire to create unit tests.
- new argument
-
writeOpenxlsx()
- New arguments
startRow
,startCol
to define starting row and column, repectively, for a new worksheet. - Argument
doFilter=FALSE
was being ignored, since the default worksheet created byopenxlsx::writeDataTable()
already enabled column filtering by default. This argument is applied properly now. - Column widths are now applied in one section of code, after the various column formatting options, which may improve column width "auto" when formatting changes the visible width of values in each column.
- Help docs were updated and formatted for better markdown style.
- New arguments
-
readOpenxlsx()
- new arguments
startCol
consistent with the same argument inwriteOpenxlsx()
, andcols
used to specify an exact vector of columns. The arguments allow loading data starting at a specific column or for specific columns in each Excel worksheet. - Added simple unit tests.
- new arguments
-
Added simple unit tests to verify that a
data.frame
saved bywriteOpenxlsx()
and re-loaded byreadOpenxlsx()
, optionally usingstartRow
andstartCol
, will reproduce the identical inputdata.frame
.
-
Fixed errors caused by
if(class(x) %in% x)
sinceclass(x)
can have >1 value, an error on R-4 and only a warning on R-3.- notably
imageByColors()
andhandleArgsText()
which called iteratively by the argument-printing utilityjargs()
.
- notably
-
reload_rmarkdown_cache()
- When using
cache.lazy=FALSE
the cache files did not save.rdx
and.rdb
files, causing this function to fail. In that case the.RData
files can be loaded but not usinglazyLoad()
so they are loaded directly into the environmentenvir
. See changes below.
- When using
-
reload_rmarkdown_cache()
-
new argument options:
file_sort=c("globals", "objects")
which defines the file order by default to use the order they appear in the RMarkdown index files"__globals"
or"__objects"
. Both files should be present, and should be identical, but the option is there to choose one or the other. -
Using globals is the new default, as it is more reliable than using file creation time:
- the RMarkdown chunks can be re-ordered, which would cause the cache file creation to be out of order from the RMarkdown document
- also chunks can be removed, and because cache files are not forcibly removed in that case, the new mechanism prevents loading un-necessary cache files which may corrupt the final environment.
-
new argument:
preferred_load_types=c("lazyLoad", "load")
to help limit the mechanism used to load cache objects. When.rdx/.rdb
files exists, the default is to uselazyLoad()
. When they do not exist,.RData
files typically always exist, and can be loaded withload()
. The option now exists to preventlazyLoad()
and to useload()
instead. Subtle difference in how R objects are stored and re-used.
-
-
numerous functions had argument help text updated for clarity.
-
sdim()
,ssdim()
,sdima()
,ssdima()
help docs were combined.
- Added MIT license.
- Added testthat unit testing.
-
middle()
- Similar to
head()
andtail()
, except it shows the middle. Actually by default it shows evenly spaced entries from beginning, middle, and end.
- Similar to
-
mixedSorts()
,cPasteS()
,cPasteSU()
- Fixed error when one or more entries were
NULL
, output now retainsNULL
without error. - Added tests to cover behavior with NULL entries, including retaining
proper names or absence of
names(x)
for input data.
- Fixed error when one or more entries were
-
getColorRamp()
- accepts
function
input fromcirclize::colorRamp2()
- accepts
character
function name with optional package prefix.
- accepts
-
coordPresets()
,drawLabels()
- new argument
preset_type
to position labels either at the plot frame (default), orpreset_type="figure"
will position labels relative to the margin around each figure.
- new argument
-
nullPlot()
- new argument
marginUnit
to specify whether to display margin units in linesmarginUnit="lines"
(default) or inchesmarginUnit="inches"
. - Margin and Outer Margin are both printed in summary four-value form, and along each side. Outer margin values are hidden when zero.
- Outer margin dotted dark green line has width=3 to make it distinct from the margin dotted line with width=1.
- new argument
-
mixedSort()
andmixedOrder()
used similar but non-identical logic when applyingignore.case=TRUE
anduseCaseTiebreak=TRUE
.- Code and logic were consolidated into
mixedOrder()
(as it should have been), and the logic was corrected to fix weird edge cases of internal capitalization within a mixed character/numeric string. - Logic essentially sorts without regard to case, then applies
a tiebreaker using case at the end. This is similar logic used by
default
sort()
, though I admit it feels weird. Defaultsort()
returnsc("aardvark", "Aardvark", "abacus", "Abacus")
. - Code consolidation should speed
mixedSort()
by almost two-fold for default settings, avoiding almost duplicating the same sort logic just to apply the case-sensitive tiebreaker. I mentioned that time hit in previous NEWS.
- Code and logic were consolidated into
-
mixedSorts()
-
Optimized to handle mixed-class, and nested or simple list.
-
When the input
list
contains multiple classes- previous behavior was to iterate the
list
otherwise class conversions (which help optimization) cause problems withfactor
andcharacter
types. For some reason, when callingunlist(x)
andx
containsfactor
andcharacter
, the output is converted tocharacter
(which is fine), howeverfactor
values are converted tointeger
thencharacter
strings of the integer values. - New behavior is to call
mixedSorts()
on subsets ofx
with the same class, so each subset is run with single-class optimization. Now instead of scaling withlength(x)
it scales withlength(class(x))
, obviously much faster.
- previous behavior was to iterate the
-
When input
list
is nested, and content is all the same class, it runsmixedSorts()
on all data en masse as is optimal. -
When input
list
is nested, and content has different classes, each subset is sorted within its class, solist
is sorted within its own subgroup. For inconsistently nestedlist
structure, various branches will be sorted together, which is slightly unoptimal, but it does maintain the input class of each atomic vector. -
All classes are maintained, without coersion to
character
.
-
-
cPaste()
- Now passes
honorFactor=keepFactors
when callingmixedSorts()
, which should provide a notable speed boost, in addition to optimizations tomixedSorts()
already described.
- Now passes
Began prep for eventual CRAN release.
- added
ComplexHeatmap
to Suggests. - edited
heatmap_row_order()
andheatmap_column_order()
to check for ComplexHeatmap.
-
readOpenxlsx()
- New default
check_header=FALSE
to sidestep issues with column headers that do not align with subsequent data.
- New default
-
formatInt()
,rmNA()
,asSize()
,sizeAsNum()
,imageByColors()
- updated to improve how it checks
class(x)
, to allow multiple values.
- updated to improve how it checks
-
mixedSort()
,mixedOrder()
defaulthonorFactor=FALSE
in vector context.- For someone mixedSorting a vector, they expect mixedSorted output.
-
mixedSortDF()
,mmixedOrder()
defaulthonorFactor=TRUE
indata.frame
orlist
context.- For someone mixedSorting a
data.frame
, they expect mixedSortedcharacter
columns, and sorted factor levels. For someone mmixedOrdering alist
, they expectcharacter
vectors to be mixedSorted and factors to be sorted by level.
- For someone mixedSorting a
-
mixedSort()
,mixedOrder()
.mmixedOrder()
,mixedSortDF()
-
gasp These core functions were ignoring
honorFactor=FALSE
and were instead always keeping factor level order without imposing its own sort order.-
The intent was to use
honorFactor=FALSE
, which was supposed to be consistent with previous versions of jamba. However, other dependent Jam functions became somewhat reliant on unintended behavior which representshonorFactor=TRUE
. This behavior is most important for uses ofmixedSortDF()
which is expected to honor factor level order by default. This expectation enables other assumptions about the order of values. That said, specific errors have been rare or non-existent thus far. -
A "problem" arises only in R versions before R-4.0.0, where default R-3.6.1
options(stringsAsFactors=TRUE)
causesdata.frame()
to convertcharacter
tofactor
. During the conversion, factor level order is defined using vanillasort()
. Therefore, usingmixedSortDF()
appears to use vanilla sort order by honoring the factor level order, but only in cases where thedata.frame
was created by a method that did not overrideoptions(stringsAsFactors=TRUE)
for consistency. So the use ofhonorFactor=TRUE
bymixedSortDF()
causes an edge case of inconsistent order for somedata.frame
objects, dependent upon the value ofgetOption("stringsAsFactors")
. -
The resolution to above issues:
mixedSortDF()
should continue to do what is expected, which in my opinion is to honor factor order by default; and- other functions which carelessly enable
stringsAsFactors=TRUE
to wreack havoc should themselves be fixed. "Check yourself, before you wreck yourself." I shouldn't have said that.
-
-
So the resolution overall is to have different defaults for
honorFactor
, even though it seems improper. I argue that it is proper:mixedSort(..., honorFactor=FALSE)
because someone callingmixedSort()
is doing so for the benefit of mixedSort behavior, otherwise they can callsort()
on afactor
and get the same result asmixedSort(..., honorFactor=TRUE)
. Therefore I thinkhonorFactor=FALSE
is expected for a vector.mixedSortDF(..., honorFactor=TRUE)
because someone callingmixedSortDF()
is doing so for the benefit of sortingcharacter
columns usingmixedSort()
logic, otherwise theirfactor
columns are assumed to have carefully (let's hope) constructed factorlevels
. And since those factorlevels
are so dear to the analyst, their order will be maintained when sorting a multi-columndata.frame
. (Or equivalent tibble, DataFrame, etc.) Therefore I thinkhonorFactor=TRUE
is expected for adata.frame
.mixedOrder(..., honorFactor=FALSE)
, due to vector context.mixedSorts(..., honorFactor=TRUE)
, due to list context.mmixedOrder(..., honorFactor=TRUE)
, due to list context.
-
jam_calc_density()
-
cPaste()
was not properly enforcingna.rm=TRUE
, which causedNA
values to be converted into"NA"
. The bug also affectedcPasteS()
,cPasteU()
, andcPasteSU()
, along with dependent functions in thegenejam
package.cPaste()
now callsrmNAs()
whenna.rm=TRUE
, to removeNA
values in relatively efficient manner across the input listx
.cPaste()
new argumentuseLegacy
will optionally enable the previous code, which was optimized forlist
that contain vectors with identical classes throughout. It had the limitation that it did not preserve factor level order, and sometimes converted factor tocharacter
in mixedlist
.
rmNAs()
is an extension ofrmNA()
applied tolist
input. It is intended to be slightly faster than iterating eachlist
element, however for now it iterates every element that contains anNA
value, in order to preserve the class of each vector.
- A warning was being issued from
rgb2col()
by checking if input argumentred
was emptylength(red)==0
, or NAis.na(red)
. However, whenred
haslength(red)>1
the second check for NA results in a logical vector ofTRUE/FALSE
, only the first of which is used in the if statement. New versions of R invoke a warning, but future versions will eventually cause an error. Nonetheless the code was updated to check for all entries inred
like this:all(is.na(red))
.
-
printDebug()
several arguments usegetOption()
:jam.htmlOut
,jam.comment
arelogical
and intended for usage inside Rmarkdown documents, to customize the output.- other arguments
jam.file
,jam.append
,jam.invert
,jam.formatNumbers
,jam.trim
,jam.big.mark
,jam.small.mark
htmlOut=TRUE
now properly includes"<br/>"
to force a line break after the output.
-
mixedSorts()
uses iterativemixedSort()
when there are different classes contained inx
, otherwisefactor
values are converted tointeger
strings. -
mixedSort()
was re-definingfactor
levels using the order of unique values, instead of the originallevels
. It was changed to uselevels
. -
mixedSort()
,mixedOrder()
,mixedSorts()
new argument.- New argument
honorFactor=FALSE
keeps previous legacy behavior, which is to perform alphanumeric sort oncharacter
values even infactor
columns. However, now this behavior can be changed.
- New argument
rowGroupMeans()
argumentrmOutliers=TRUE
along withcrossGroupMad=TRUE
incorrectly caused therowStatsFunc
to be redefined. This bug was fixed. Also, whenreturnType="output"
it no longer returns the attributes"n"
and"nLabel"
which are intended to represent the number of non-NA replicates per group, and this information is not relevant to the input data.
-
printDebug()
bug fixed:- Occurred when
bgText
had length=1, or any element in thelist
had length=1. - Improperly tried to determine how to make alternating light/dark color without first checking the luminance of the color in this scenario.
- Occurred when
color_dither()
simply takes one color, and returns two colors that differ by a minimum contrast, with the same hue. Not coincidentally it substitutes into theprintDebug()
function.
cell_fun_label()
was updated to skip cells with no text, vastly improving rendering speed for heatmaps that contain a large proportion of blank labels.
-
printDebug()
was updated:- Argument help text was updated.
- Argument
indent
is honored, previously ignored. Whennumeric
it defines the number of character spaces" "
used to indent. - When a color is adjusted to light,dark alternating pattern,
color2gradient()
is called usingdex=1
instead ofgradientWtFactor=1
, which should apply more consistent scaling to light and dark colors. - New argument
dex
used to control intensity of light,dark color adjustment. Whendex=0
no adjustment is performed. - The
bgText
light,dark adjustment now usesdex
as well, for consistency. - When
doColor=FALSE
, the output enforces conversion offactor
tocharacter
when combining multiple values into a string, consistent withdoColor > 0
behavior. Should be minor effect if any.
-
setPrompt()
updates:- new argument
debug
to print the control characters - new default
addEscapes=NULL
, where it autodetects whether it is running inside RStudio, settingaddEscapes=TRUE
if not running inside RStudio. WhenaddEscapes
is defined, that setting is honored.
- new argument
-
drawLabels()
-
default box color is much lighter, less saturated.
-
new argument
panelWidth
to size labels to plot panel width, mostly useful for labels at the top or bottom of each plot panel. This argument is intended to be used by thejamma
package to place plot panels above each plot, at least the full width of each plot panel.panelWidth="force"
labels always equal full panel widthpanelWidth="minimum"
labels are at least full name width, or as wide as necessary for the text labelpanelWidth="maximum"
labels are as large as needed for text label but no wider than the plot panel.
-
-
col2hsl()
andhsl2col()
help convert colors to and from HSL color space- See examples for
col2hsl()
for visual comparison between HCL and HSL - Note that both functions require the
farver
package, and may become a formal dependency ofjamba
. - The most dramatic selling point for HSL is that values are typically very consistent within Hue, without distortion during interconversion and adjustments. In contrast, HCL "caps" colors at the color gamut for each RGB channel individually, which can have rather dramatic effects on the hue - sometimes fundamentally changing the color hue more than 80 degrees! More commonly, color hues are shifted by HCL conversion in order to represent Chroma and Luminance. Sometimes the result is faithful Chroma and Luminance of a completely different hue, however, which is not ideal. (Note that other color packages such as prismatic have internal functions to detect whether a color is in gamut, so it can pre-adjust the color before conversion in the farver package. Again, not ideal.)
- HSL does have the property that colors with the same "Lightness"
are not the same perceived "Luminance" as with HCL. That said, for
me this property may be advantageous, as the "yellow" hue for example
is rather desolate when the Luminance and Chroma is toned down to
comparable levels of blue and purple. Instead, the most saturated
color for each hue is seen with
S=100
andL=50
. With HCL, every hue has its own local Luminance values for the maximum Chroma, and the maximum Chroma varies substantially across all hues.
- See examples for
-
breaksByVector()
was updated to:- enforce consistent vector names for each output,
changing
breakPoints
andlabelPoints
to represent the unique values in the order they appear. - added
breakLengths
to the outputlist
for convenience.
- enforce consistent vector names for each output,
changing
-
imageByColors()
adjustments- moved
imageByColors
into its own R filejamba-imagebycolors.R
. - fixed error with
doTest=TRUE
, which now returns test data invisibly. - The
cexCellnote
input is somewhat confusing and may change in future. To supply cex values for each column or row, uselist
input forcexCellnote
, where each list element represents a column or row, respectively.
- moved
-
showColors()
was updated to accept colorfunctions
in two forms:circlize::colorRamp2()
form, which contains attributes"colors"
and"breaks"
that define the underlying color gradient. These colors are converted to hex, named by"breaks"
, then displayed.- All other
function
are expected to accept an integer number, and return that many colors, which are named by the integer index, with default length n=7. - If either above method fail, the output colors are not displayed.
-
showColors()
updates:- also updated to handle
par("mar")
properly, and to returnNULL
when input is empty, instead of throwing an error. - new argument
makeUnique=TRUE
to display the first unique color in each color vector. - it was moved to its own R file.
- also updated to handle
-
pasteByRowsOrdered()
- new argument
keepOrder=FALSE
, no change to default behavior. WhenkeepOrder=TRUE
, anycharacter
columns are converted tofactor
whose levels are defined by the order of unique existing entries, keeping the order provided inx
. - new argument
byCols
passed tomixedSortDF()
to define the order of column sort for factor levels. This argument was previously passed via...
, but was added as a specific argument to make this connection more apparent.
- new argument
-
call_fn_ellipsis()
was added.- This function is a wrapper around an internal function call: within a function, calling another function.
- The function allows passing named arguments in
...
to a function that does not permit...
but which may match some argument names in...
. call_fn_ellipsis()
only passes named arguments that are permitted in the subsequent function.- Form before:
some_function_call(x, ...)
- Form after:
call_fn_ellipsis(some_function_call, x, ...)
-
rowGroupRmOutliers()
is a convenience function that callsrowGroupMeans(..., rmOutliers=TRUE, returnType="input")
.- new argument
crossGroupMad=TRUE
calcualted the row MAD value using the median MAD per row, using non-NA and non-zero MAD values. See description of changes below.
- new argument
-
Moved
rowGroupMeans()
androwRmMadOutliers()
into a specific .R file for easier management. -
rowGroupMeans()
changes whenrmOutliers=TRUE
:-
new argument
crossGroupMad=TRUE
will:- calculate each group MAD,
- take the median non-zero, non-NA MAD for each row as
rowMadValues
- the median non-zero, non-NA
rowMadValues
is defined asminDiff
rowMadValues
andminDiff
are passed torowRmMadOutliers()
for each group, which therefore applies the same threshold to each group on a row, and with the sameminDiff
difference-from-median required.- These changes ensure that row MAD values are not
0
unless all groups have MAD=0 on the same row. - Also, the default
minDiff
will by default require a point to differ at least more than the median difference observed from median in each row, in each group. If all MAD=0 in all groups and all rows, thenminDiff=0
in which case it likely does not have adverse effect.
-
-
rowRmMadOutliers()
changes:- new argument
rowMadValues
can define the MAD values on each row, useful for setting the per-row MAD across multiple sample groups for example. - new argument
minReps
to require this many non-NA values, only useful when providingrowMadValues
values, and for rows that have n=2 replicates. includeAttributes=TRUE
now includes attribute"outlierDF"
which is a adata.frame
with summary information for each row in inputx
.
- new argument
-
writeOpenxlsx()
changes- New argument
wb
to supply an existingWorkbook
object, instead of loading it from a file. - It now returns the
Workbook
object withinvisible(wb)
. - If
file=NULL
then output is not saved. - To save multiple sheets to the same file, it is substantially
faster to build up one
Workbook
object, then save thatWorkbook
one time at the end. - New argument
colWidths
will apply column widths to theWorkbook
internally, to avoid having to save, read, apply, and save.
- New argument
-
applyXlsxConditionalFormat()
,applyXlsxCategoricalFormat()
,set_xlsx_colwidths()
,set_xlsx_rowheights()
xlsxFile
can be a filename orWorkbook
object- each function returns
Workbook
invisibly
-
mixedSortDF()
was updated:df
input objects with zero rows are returned directly.- Bug fixed for error thrown for objects with zero rows and no rownames,
caused by 0.0.76.900 which inserted
NA
for empty rownames, but caused an error when thedf
had zero rows, sinceNA
has length 1 and did not match the number of rows. First, zero-row objects are returned, no need to sort. Second, the section was rewritten to be more robust, now empty rownames are removed prior to callingmmixedOrder()
. - The function now properly allows sort by character
byCols
for data with no colnames, useful when sorting by"rownames"
. - Added examples that test and confirm the desired behavior.
-
plotRidges()
is analogous toplotPolygonDensity()
except that it usesggplot2
andggridges
to plot density profiles inside the same panel. Particularly good for comparing densities across columns/samples, and when there are a large number of samples. -
cell_fun_label()
is a wrapper function to add text labels toComplexHeatmap::Heatmap()
. It is somewhat configurable:- It can display a combination of one or numeric or character labels.
- Label text color is intended to use a color that contrasts with the
color of the heatmap cell itself, using
setTextContrastColor()
. - It can optionally draw an outline to each cell.
- Numeric values are optionally abbreviated, for example
1502110
would be displayed1.5M
. - Text font size can be directly adjusted.
- Labels can be rotated inside each cell, useful when cells are tall-skinny.
The packagedown function categories were slightly re-ordered, and may be re-grouped in future to help organize functions.
-
reload_rmarkdown_cache()
will load the cache files stored after processing an Rmarkdown.Rmd
file. It is intended to help restore the Rmarkdown data available to particular Rmarkdown chunks, or to restore the entire session so the data can be used for more analysis or visualization.- optionally loads into a specific
environment
- optionally loads until a specific Rmarkdown chunk
- optionally loads only a given number of Rmarkdown chunks in order
- optionally loads into a specific
-
color2gradient()
new argument defaultgradientWtFactor=NULL
:gradientWtFactor
controls the intensity of the light-to-dark color gradient, wheregradientWtFactor >= 1
defines a broader range from light-to-dark, andgradientWtFactor < 1
defines a more limited light-to-dark. For example, whenn=2
it there does not need to be as large a difference in brightness for color1 and color2.- New behavior assigns default
gradientWtFactor
based uponn
.
-
color2gradient()
argumentgradientWtFactor
can be supplied as a vector, so the value will be applied to each gradient created, in order.
mixedSortDF()
had a bug when supplied withmatrix
that had norownames()
, it would fail because the intermediatedata.frame
was assignedrownamesX=rownames(x)
and thus had zero length. It now assignsrownamesX=rmNULL(nullValue=NA, rownames(x))
which fills the column withNA
values.
Ported two functions from multienrichjam.
heatmap_row_order()
,heatmap_column_order()
are specifically used with Bioconductor packageComplexHeatmap
heatmaps. These functions were enhanced to handle several scenarios: presence of absence ofrow_groups
,column_groups
; with and withoutrownames()
,colnames()
in the data matrix; with and without specificrow_labels
,column_labels
.
diff_functions()
is a simple utility function intended to compare the text in two functions, motivated while migrating functions into R packages, while needing to make changes in the old function source, propagating to the new function source. Currently the function requires access to commandline tool"diff"
which likely limits this function to linux-like operating systems, MS Windows System Linux (WSL), or Cygwin on MS Windows.
plotSmoothScatter()
was improperly definingxlab
andylab
when supplied with adata.frame
ormatrix
with colnames. The steps now closely matchgraphics::plot.default()
.noiseFloor()
was not checking forminimum
to beNULL
, though this error has not occurred myself, that step is now performed as it would have thrown an error.
renameColumn()
when theto
values were supplied asfactor
values, they were coerced by R intointeger
and therefore lost the character string values provided. The workaround is to coerceto
withas.character()
which is straightforward for processes outsiderenameColumn()
, however the expected behavior is certainly to maintain the character string, so this function has been updated accordingly. The situation tends to happen when the column renaming is stored inside adata.frame
and the rename "to" column typefactor
is not checked beforehand. It is a rare scenario, but warrants a fix. In addition,renameColumn()
also operates onGRanges
and related genomic ranges objects, and that step requiresIRanges::values()
generic function. Thevalues()
functions were updated to include the proper package prefix, in the event those packages had not already been loaded. This function now explicitly requireslength(from) == length(to)
. The help text was updated with more information.
mixedSortDF()
argument defaultuseRownames=TRUE
was changed touseRownames=FALSE
to protect against extremely slow sort behavior with largenrow
data, which would previously by default sort all rownames even when not required. The new behavior only sorts the columns specified, and can enable rownames as a tie-breaker withuseRownames=TRUE
or by includingbyCols=0
.getColorRamp()
now accepts gradient names supplied bycolorjam::jam_linear
andcolorjam::jam_divergent
, when the"colorjam"
R package is available. The linear gradients differ mainly in subtle ways, emphasizing more color saturation in the mid-range values, motivated by their use in coverage heatmaps.
- Not really a bug, but
mmixedOrder()
was apparently enabling verbose output by default by usingverbose - 1
, and how did I not realize thatif (-1) cat ("yes")
would print"yes"
? Geez. This bug also causedmixedSort()
andmixedSortDF()
to print extremely verbose output by default.
Reminder to myself to use options(pkgdown.internet=FALSE)
when behind VPN.
And sometimes when not behind VPN...
sizeToNum()
performs the opposite function asasSize()
, it takes an abbreviated size as a character string, and converts tonumeric
value.
mmixedOrder()
was updated to fix a bug when sorting numbers with class"integer64"
, which is defined bybit64::integer64
. These values were produced byopenxlsx::read.xlsx()
that contained large integer values, and were previously ignored bymmixedOrder()
. The change also fixes a bug inmixedSortDF()
, however this bug did not affectmixedSort()
andmixedOrder()
. The conditional now testsis.numeric()
which returnsTRUE
forbit64::integer64
types, and hopefully this logic will work for future large numeric types.mixedSort()
fixed an issue whereignore.case=TRUE
caused factors to be sorted alphanumerically instead of by factor level. The new and intended behavior is to sort by the unique uppercase factor levels, otherwise maintaining the factor level order.rbindList()
was updated to change the wayreturnDF=TRUE
is handled. It now simply callsdata.frame(x, check.names=FALSE)
, with no further validation. Previously this option called a functionunlistDataFrame()
that did not get ported intojamba
, and probably will not.
-
mixedSortDF()
was enhanced to allow row name sort, using these formats:byCols="rownames"
orbyCols="row.names"
orbyCols=c(0)
. Reverse row name sort can be accomplished bybyCols="-rownames"
orbyCols="-row.names"
orbyCols=c(-0.01)
. WhenbyCols
containsnumeric
values, the sign is taken first so any negative values will reverse the sort, then values are rounded to integer values. SobyCols=-0.1
will reverse sort by row names, useful when it is more convenient to providebyCols
as anumeric
vector than acharacter
vector. -
mixedSort()
was refactored to simplify the logic, and to correct small issues, for example whenignore.case=TRUE
andx
is a factor, the previous behavior would calltoupper()
which convertsx
tocharacter
, and which is sorted as such. The new intended behavior is to sort byunique(toupper(levels(x)))
to maintain factor level order as defined. The new logic defines a transform function forx
, whose output is passed tomixedOrder()
. For example, whensortByName=TRUE
the transform function passesnames(x)
tomixedOrder()
. Otherwise, there is only one call tomixedOrder()
and no data is copied during the process, which should be reasonably memory-efficient for large sort operations. Frankly, it needs one more refactor to push all the logic intomixedSort()
. -
mixedSortDF()
,mixedSort()
, andmmixedOrder()
had arguments extended to represent all arguments inmixedOrder()
, so the sort customizations are properly passed between functions.
Some R functions were moved into separate files for easier management. More work should be done over time to reduce the number of functions in each file. Some files have 15 to 31 functions!
asSize()
was moved fromjamba.R
intojamba-size.R
.mixedSort()
functions were moved intojamba-mixedSort.R
.
lldf()
new argumentuse_utils_objectsize=TRUE
to preferutils::object.size()
instead ofpryr::object_size()
after observing some cases where object sizes were vastly over-stated for unusual Bioconductor object types. It is unclear to me exactly how the memory usage is determined, and which function is correct, so for now the two alternatives will remain inlldf()
.
-
readOpenxlsx()
was updated to fix a small bug when loading multiple sheets in one pass. It should now work as expected to runreadOpenxlsx()
on any xlsx file, and return alist
ofdata.frame
objects representing each worksheet in the xlsx file. -
readOpenxlsx()
new argumentscheck_header
andcheck_header_n
are intended to check for header rows, recognized as rows with a different number of columns than subsequent rows of data in each sheet. Whencheck_header=TRUE
it will check the firstcheck_header_n
rows to determinencol()
andsclass()
on each row loaded individually. When header rows are detected, the first value of the first row is assigned to columndimnames
of thedata.frame
returned, and the full header data is included as an attributeattr(df, "header")
. This method is intended to help when loading multiple worksheets, and none, some, or all worksheets may have header rows. -
Note this methodology is being tested currently, to debug edge cases where data is sometimes detected to have fewer columns in some rows than others. The intent is to expect
skipEmptyCols=FALSE
to return all columns even when there is no data present, for consistentncol()
from data rows, and fewer columns for header rows. The logic may be updated over time. -
readOpenxlsx()
was updated to applyskipEmptyCols=FALSE
by default for each step, to avoid inconsistencies especially when the column headers are not defined for all columns, or data is not present in all columns with column headers.
rowGroupMeans()
was updated to remove a silent dependency onmatrixStats
and now properly checks the dependency, and calls with prefixmatrixStats::rowMedians()
andmatrixStats::rowMads()
as needed.applyXlsxCategoricalFormat()
was updated to streamline the categorical color matching, though not by much for large files. Will revisit and improve speed eventually.- Fixed some help documents not using markdown format when referring to other package functions.
igrepl()
is a convenient wrapper forgrepl(..., ignore-case=TRUE)
writeOpenxlsx()
new argumentwrapCells=FALSE
changes the previous behavior so that cells are not word-wrapped by default. Previously, when column width did not accomodate the text, cells would be tall - and sometimes "super-tall". The functionset_xlsx_rowheights()
can be used to fix this situation, however that process can be quite slow for large Excel worksheets.
provigrep()
argumentmaxValues
had not beedn implemented properly when applying a limit to returned values per grep pattern. This implementation has been corrected. Examples have been updated to demonstrate its utility.
heads()
applieshead()
across a list of atomic vectors, using a one-step style that is notably faster thanlapply(x, head, n)
especially for long lists. Also it can apply a vector ofn
values if needed. Its main utility is forprovigrep()
with argumentmaxValues
.proigrep()
was added as a lightweight alias toprovigrep(..., value=FALSE)
which returns the index positions rather than the values.match_unique()
matches unique vector values to the full vector. I found myself performing this step so many times I thought a function might feel better. It may also be equivalent towhich(!duplicated(x))
- but again, that doesn't feel easy enough. I guess.
lldf()
is a lightweight extension toutils::ls()
that returns adata.frame
with object name and size, sorted largest to smallest. I found myself using this function several times after becoming more aware of object sizes while usingjamsession::save_jamsession()
.
plotSmoothScatter()
default argumentbandwidthN=NULL
which changes the default bandwidth to usebwpi
for the per-inch calculation of the bandwidth that can be reasonably displayed given the output size. Previous default wasbandwidthN=300
. Note that the output density calculation is dependent upon the display size, which can affect the results.plotSmoothScatter()
now honorsxlab
andylab
, and when those are not provided, it uses base R convention and appliesdeparse(substitute(x))
to determine a suitable default label.
shadowText()
new argumentshadowOrder
to control the rendering of shadows and labels for a vector of labels:shadowOrder="each"
renders each shadow then each label in order, so that subsequent shadows will overlap previously rendered labels;shadowOrder="all"
renders all shadows at once then all labels, so that shadows will never overlap labels. Very minor issue, mostly affecting display of labels that slightly overlap - see examples inshadowText()
.setCLranges()
fixed issue in first time processing, which was wrongly defining Crange and Lrange for future use even inside Rstudio. (Minor issue that would only affect text labels with light colors on a light background.)
fix_matrix_ratio()
had a bug in secondary logic referring to non-existent objecty
. This function is used as an optional backend forimageDefault
whenuseRaster=TRUE
to provide reasonable default matrix adjustment to reduce or prevent visual distortion when image interpolation is performed on matrices with non-1:1 ratio of rows and columns.
readOpenxlsx()
is the reciprocal towriteOpenxlsx()
that differs fromopenxlsx::read.xlsx()
mainly in that it loads multiple sheets at a time, and does not mangle column names whencheck.names=FALSE
. Theopenxlsx
method behaves as ifcheck.names=TRUE
in all cases, as of 01-Dec-2020.
getColorRamp()
argumentdefaultBaseColor="grey99"
from the previousdefaultBaseColor="grey95"
which just felt too dark.plotSmoothScatter()
new argumentcol
passed tosmoothScatterJam()
to be compatible withsmoothScatter()
, this defines point color whennrpoints
is non-zero. Apparently not defining this argument allowed R to do fuzzy argument name matching, causing conflict withcolramp
.plotSmoothScatter()
new argumentexpand
will expand the x-axis and y-axis ranges by this amount. The defaultexpand=c(0.04, 0.04)
mimics the default setting for R base plots. The help text was updated.plotSmoothScatter()
now usesgrDevices::xy.coords()
to define coordinates, avoiding internal logic that essentially did the same thing. This change should be silent. This change does remove the warnings that were produced with input supplied as a single numeric vector.
plotSmoothScatter()
argumentbinpi
was setting the bins per inch identically for x and y axes, using the maximum size -- when it can and now does handle each axis independently. Now the output pixels should be square, rather than being influenced by the ratio of the plot device.
getColorRamp()
was updated for single-color input anddefaultBaseColor
. It now properly creates a color gradient from light-to-dark, or dark-to-light based upon the relative brightness ofcolor
anddefaultBaseColor
.
Updates to setCLranges()
mainly affect colorized console
text output, used by printDebug()
which calls make_styles()
.
This function is also useful to adjust a color or vector of
colors for contrast on a light or dark background.
setCLranges()
argument has new defaultlightMode=NULL
and slightly different, more intuitive behavior. WhenlightMode
is defined (TRUE
orFALSE
) then it over-rides existing values, and uses the correspondinglightMode
setting directly. Otherwise, whenlightMode=NULL
any existingCrange
andLrange
values are used. If none are defined, thencheckLightMode()
is called, then default values are used.- Functions that use
setCLranges()
were updated so the argument defaultlightMode=NULL
is used. When those functions are called withlightMode=TRUE
orlightMode=FALSE
the text output will be adjusted. For example:
printDebug("yellow", lightMode=FALSE)
printDebug("yellow", lightMode=TRUE)
Functions affected:
checkLightMode()
applyCLrange()
setCLranges()
printDebug()
make_styles()
jargs()
printDebug()
failed on class"package_version"
ultimately becauseunnestList()
could not unlist this object type. The "package_version" class is a list, e.g.is.list(packageVersion("base"))
isTRUE
. However, accessing the first item, e.g.x[[1]]
always returns the full object unchanged... which is not expected behavior for a list. This class was added tostopClasses
.unnestList()
was refactored to handle nested lists with and without names in various combinations, and to usetryCatch()
as a final protection from infinite recursion, when list-list objects do not behave like list objects (as is the case with the"package_version"
class.)applyCLranges()
was updated to remove the warning message for argumentfixYellow
that read"the condition has length > 1 and only the first element will be used"
. The function now handles vector input forfixYellow
and extends the vector to the length ofx
.
plotSmoothScatter()
now correctly determines the plot aspect ratio after the plot is initiated. The situation occurs when usinggraphics::layout()
which does not update thepar()
settings until the plot is created. Now a blank plot is initiated before determining aspect ratio, which allows proper calculation of the 2D density plot.
plotSmoothScatter()
new argumentbinpi
defines thenbin
number of displayed bins based upon plot panel size. The defaultbinpi=50
defines 50 display bins per inch. This value will adjust accordingly for large and small figures, based upon the physical size of the figure in inches.plotSmoothScatter()
argumentnbin
new default isnbin=NULL
, which then usesbinpi
to calculatenbin
. To use the previous style, setnbin=256
which will ignorebinpi
.plotSmoothScatter()
new argumentbwpi
definesbandwidthN
based upon the plot panel size. The defaultbwpi=NULL
does not implement this scaling by default, insteadbandwidthN=300
is still the default. The benefit of usingbwpi
is mostly in speed of calculating 2D density for multi-panel plots where detail would already be lost during display.
plotSmoothScatter()
uses two arguments to determine how
data is plotted:
bandwidthN
defines the number of bandwidth divisions on the x- and y-axes used to calculate the 2D density. HigherbandwidthN
calculates greater detail in the 2D density -- these values are all typically higher thangraphics::smoothScatter()
, and this is still the driving reason to useplotSmoothScatter
and notsmoothScatter()
.nbin
defines the number of visible pixels used to display the calculated 2D density. Highernbin
creates visually more detailed representation of the 2D density.
Usually nbin
and bandwidthN
values are similar to each other,
since it conceptually makes sense to calculate 2D density at
roughly the resolution used to display the results.
These arguments are adjustable
and are still valid for most purposes.
So why the change? The short summary is that multi-panel plots
have fewer pixels being displayed, and I wanted a convenient method
to reduce the number of pixels (nbin
) displayed in each panel.
(Truth be told, while working from home creating plots on remote servers,
I noticed just how long multi-panel plots take to render. Most of that
time is spent rendering detail never seen during display.)
After some extended testing, I concluded that bandwidth should remain relatively constant regardless of the display pixels, in order to maintain consistent 2D density despite the image size. (Conceptually, it makes sense that the image display size should not affect underlying calculation of the data to be displayed.) However, the number of displayed pixels should be reduced roughly proportional to the size of the plot panel, which solves the issue I was having of plotting data with far more detail than could be visually rendered, making plots larger, take longer to display, and creating larger saved file sizes.
Also, the resolution of the resulting plot can now be adjusted relative to the output plot size, consistent with computer monitor resolution (dots per inch dpi), and printed paper output dpi.
applyXlsxConditionalFormat()
andwriteOpenxlsx()
were updated to make default colors innumStyle
,intStyle
,pvalueStyle
slightly more colorful, while also being less dark, so Excel default black text has better visible contrast. (Why can Excel not apply conditional format rules to text font color?)writeOpenxlsx()
format for P-valuespvalueFormat
formats values above 0.01 as decimal value such as0.022
or0.157
, P-values below 0.01 are exponential notation such as2.31E-10
. (I wish R could avoid formatting things like1.1e+00
and1.0e+01
without using a custom function.)writeOpenxlsx()
was updated with a more comprehensive example.applyCategoricalFormat()
has a simple working example.applyXlsxConditionalFormat()
has a simple working example.
set_xlsx_rowheights()
andset_xlsx_colwidths()
are light wrappers to the very useful functionsopenxlsx::setRowHeights()
andopenxlsx::setColWidths()
. They simply open the workbook, apply the values to the appropriate sheet, then save the workbook.
setPrompt()
by default wraps the color sequence inside proper ansi escape sequences, which helps the console properly apply word wrapping by ignoring color sequences in the estimate of character count per line.
printDebug()
fixed a visual glitch caused by usinggsub()
to remove trailingsep
characters from vector elements before adding thesep
itself, without removing ANSI-encoding from thesep
string, sometimes removing trailing zero from numeric strings but only in the middle of a multi-element vector. Now thesep
is appended only usingpaste0()
and no trailingsep
characters are checked nor removed. This behavior is probably better since it should properly represent the input content.printDebug()
was modified to fix a longstanding visual glitch that would not fully reset inverted ANSI colors that span multiple lines. If the output uses color, a trailingcrayon::reset("")
is added to the end of each line.
jam_rapply()
is a lightweight customization tobase::rapply()
, specifically designed to keepNULL
entries without dropping them silently. It has the added benefit of being able to flatten a nested input list, then expand back into the original nested list structure, without losing theNULL
entries.
A theme of several updates this version has been to handle list
input that may contain factor
and non-factor
vectors.
In fact even handling a list of factor
vectors is unclear
at least to me. For example, base::unlist()
operating on a
list of factors will define one factor vector whose levels
are literally the unique first-occurrence of each factor level.
For example sort(factor(c("A","B"), levels=c("A","B")))
results
in c("A", "B")
, while sort(factor(c("A","B"), levels=c("B","A")))
results in c("B", "A")
. So what should be done when given:
list(factor(c("A","B"), levels=c("A","B")), factor(c("A","B"), levels=c("B","A"))
In reality, most such occurrences would not happen, if factor levels
are specified, the best solution is to include the full set of factor
levels with each factor vector. But if the input contains a mixture
of factor and character, vectors, running unlist()
converts factors
to integers... which is really bad. At the very least I had to
handle and prevent that scenario.
pasteByRowOrdered()
was modified in two ways: new argumentna.last=TRUE
is passed tomixedSortDF()
to allowNA
values to be sorted at the top, which seems intuitive for most scenarios; also the...
additional arguments are passed tomixedSortDF()
which allows column sort order to be customized. PreviouslypasteByRowOrdered()
calledmixedSortDF()
which sorted columns in the order they appear in thedata.frame
, however sometimes it is better to sort columns differently, while keeping the original column order intact. See examples for illustration ofna.last=TRUE
. In a two-column table withNA
values in the second column, usingna.last=TRUE
(default) would yield factor levelsc("A_B", "A", "B_C", "B")
, while usingna.last=FALSE
would yieldc("A", "A_B", "B", "B_C")
. This output seems more intuitive, however the default inmixedSortDF()
andmixedSort()
arena.last=TRUE
so that default will be maintained for consistency.mixedSort()
argumentNAlast
is deprecated in favor ofna.last
for consistency withbase::sort()
.
cPaste()
was refactored to simplify internal logic, and to handle a rare edge case that was inconsistent with related functions. It occurs when the input list contains somefactor
vectors, and some non-factor
vectors, and when bothdoSort=TRUE
andkeepFactors=TRUE
. ThekeepFactors=TRUE
argument tries to maintain factor levels during the sort, instead of usingmixedSort()
across all vectors. In this case, previously the non-factor
vectors were converted to factor, which by default would order factor levels usingsort()
. Now the output is consistent in that thecharacter
vectors are converted to factors whose levels are ordered usingmixedSort()
. The step occurs once across allcharacter
vectors, so it is fairly fast even for large input lists. Also, anyNULL
entries are still maintained and returned as""
.mixedSorts()
was updated to allow input that has no names, which was errantly returningNULL
. Now names are handled gracefully, allowing no names, or even duplicated names, without issue.mixedSorts()
now properly handles nested list input that may containNULL
, so that it returns the same structured list includingNULL
entries where appropriate.
uniques()
new argumentuseSimpleBioc=TRUE
will optionally enable Bioconductor SimpleList intermediate -- mostly available to benchmark because it is so painfully slow it raised a red flag. The BioconductorS4Vectors
package changed how they handleList
coersion from a simplelist
class, instead of usingCompressedList
it defaulted to useSimpleList
. Unfortunately,SimpleList
is roughly 6-10 times slower when callingunique()
, and was causing curious slowdowns in other functions such ascPasteU
. Bioconductor does not allow coersion directly toCompressedList
, instead requires coersion by specific recognized classes such as"character"
with"CharacterList"
, and"integer"
with"IntegerList"
. So because the input list is allowed to contain different classes, the remedy is to make aCompressedList
for each recognized class, calluniques()
on thatCompressedList
, and repeat until all classes are handled. Any unrecognized classes are handled usinglapply(x, unique)
. See examples for some benchmark comparisons. WhenuseBioc=TRUE
, the optimized Bioconductor method is used. WhenuseBioc=FALSE
, anduseSimpleBioc=TRUE
, the slower Bioconductor approach is used, which usesSimpleList
as an intermediate. When bothuseBioc=FALSE
anduseSimpleBioc=FALSE
, there are two additional options:keepNames=FALSE
useslapply(x, unique)
and loses vector names;keepNames=TRUE
will invoke a special base R approach that maintains the original vector names for the remaining unique entries. Of these four approaches the timings relative to the fastest:
- useBioc=TRUE: 1x (fastest)
- useBioc=FALSE, useSimpleBioc=TRUE: 6x slower
- useBioc=FALSE, useSimpleBioc=FALSE, keepNames=FALSE: 1.8x slower
- useBioc=FALSE, useSimpleBioc=FALSE, keepNames=TRUE: 12x slower
printDebug()
has a new argument, largely silent,doReset
which defines whether to apply an additional color reset to the delimiter argumentsep
. Previously the delimiter inherited the color from the previous text, but now by default the delimiter style is reset, giving more clear distinction between multiple values.printDebug()
now properly applies the Crange and Lrange values when lightMode is TRUE, which means it limits the brightness of text colors on a light background, to ensure enough contrast to read the text. When usingprintDebugI()
the background color is not adjusted, and the foreground (text) color is set usingsetTextContrastColor()
, meaning either white or black depending upon the background brightness.setCLranges()
andmake_styles()
were updated to apply options"jam.Crange"
,"jam.Lrange"
only when those options wereNULL
, otherwise leave them as-is.applyCLrange()
now properly applies the desiredCrange
andLrange
values, and defines the appropriate options, by default only when those options areNULL
.fixYellow()
default settings were changed to expand the range corrected "for green-ness", alsofixup=TRUE
by default.hcl2col()
argument was changed tofixup=TRUE
, andmodel="hcl"
, consistent with other changes in color handling.hcl2col()
andcol2hcl()
now usemodel="hcl"
by default, which now calls thefarver
package if installed, otherwise they revert to using colorspacemodel="polarLUV"
andfixup=TRUE
. In future colorspace will likely be removed in favor of farver, so for now the transition has begun.setTextContrastColor()
was adjusted to handle alpha transparency more accurately, the examples were updated and include a new example that usesdrawLabels()
on a dark background. New argumentalphaLens
allows some fine-tuning of the alpha transparency blending of foreground and background colors.
Added some visuals to README.Rmd.
shadowText()
was updated to use severaloptions()
as default argument values. Althoughoptions()
is not always an ideal mechanism, for purely visual effects it is not in conflict with statistical reproducibility, and allows some overall graphical settings to be maintained whenshadowText()
is being called through internalplot()
functions. For example settingtext <- jamba::shadowText
then calling a default base R plot function will use thejamba::shadowText()
in place oftext()
, but without allowing any customization. Theoptions()
mechanic allows some custom settings to be honored. The primary driver for these changes is inmultienrichjam::jam_igraph()
which plotsigraph
objects with some customization, one option isuse_shadowText=TRUE
which invokesjamba::shadowText()
. It is desirable to adjust the contrast of the outline effect so it does not completely obscure the underlying network graph display.
fix_matrix_ratio()
is used to expand a matrix to have roughly 1:1 dimensions, up to a maximum factor per dimension. The purpose is to enhanceimage()
,rasterImage()
, andgrid.raster()
functions, specifically wheninterpolate=TRUE
for images with more rows or columns than there are actual pixels to display the image. Theinterpolate=TRUE
methods in base R do not account for assymetry, nor do they account for a low number of rows or columns. See examples for visible examples of the effect.
The README.Rmd was re-organized, with more callouts of
helpful jamba
functions. Next step will be to include
visual examples.
writeOpenxlsx()
was exporting files with inconsistent word wrapping by column, and inconsistent vertical align (valign
) settings. The culprit wasopenxlsx::saveWorkbook()
which appears to apply default styles for cell styles that are not specifically encoded. Simply loading and saving a workbook would modify column styles. The workaround/fix was to ensurewriteOpenxlsx()
would specifically encodewrapText
andvalign
for each cell, so that it would not be overridden byopenxlsx::saveWorkbook()
mood.writeOpenxlsx()
now forceswrapText=TRUE
for all columns. In future the function may allow per-columnwrapText
.applyXlsxCategorical()
has new argumentwrapText=TRUE
which is passed toopenxlsx::createStyle()
, since that function requires wrapText be eitherTRUE
orFALSE
, and its default isFALSE
.
setTextContrastColor()
no longer callspar("bg")
to determine the background color, unless a graphics device is already open. This change will prevent a graphics device from being opened in somewhat random situations. The argumentbg
is only used when inputcolors
have alpha transparency. Whenbg
is not supplied, it will querypar("bg")
only whenlength(dev.list())>0
, otherwise it uses"white"
by default. Note that callingpar()
always opens a new graphics device if one is not already open, even though the"bg"
value is stored somewhere and should not require a new device. The R docs do describe this behavior, for what it's worth.imageByColors()
now accepts argumentcellnote
as an atomic vector, which is coerced to a matrix with same dimensions as input matrixx
. This change makes it easier to use numeric formatting functions, which sometimes take matrix input and provide vector output.applyCLrange()
new argumentfixup
which is passed tohcl2col()
which in turn passes it tocolorspace::hex()
when converting colors outside the color gamut. These functions will soon be replaced with calls tofarver
.hcl2col()
andcol2hcl()
now have argument optionmodel="hcl"
that uses farver, and its color model"hcl"
, which is equivalent to usingcolorspace::hex(...,fixup=TRUE)
, except faster, and with better upside for other color manipulations. For now, the color model will not use"hcl"
until I can work out better default values incolorjam::rainbowJam()
.
rbindList()
has two optional arguments:
sdima()
andssdima()
are equivalent tosdim()
andssdim()
except that they operate onattributes(x)
. I somehow found myself constantly typingsdim(attributes(x))
and finally had enough of that.printDebugI()
is a shortcut toprintDebug(..., invert=TRUE)
, intended to be a quick way to use inverted colors, to colorize the background instead of the text. Note thatprintDebug()
applies a color range restriction, to make sure the text contrasts with either light or dark background. Wheninvert=TRUE
the background color is not restricted, instead the foreground text usessetTextContrastColor()
to determine a suitable contrasting color for the text and its corresponding background color.
imageByColors()
was refactored to handle grouped labels more cleanly. New argumentgroupByColors=TRUE
decides whether to group cellnotes only when the label and underlying color are both identical -- which is a change from previous behavior. Previous behavior grouped consecutive identical labels, regardless the underlying color, which is sometimes helpful, for example labeling a color gradient by the base color. Typically the cellnote and color would change together, but not always. The new default is consistent with the expected behavior.imageByColors()
new argumentgroupBy
with one or both values"row"
which groups cellnote values by row, and"column"
which groups cellnote values by column. Useful to limit cellnote grouping so the values are not grouped inappropriately. This argument is mostly useful whengroupByColors=FALSE
.imageByColors()
new argumentadjustMargins=TRUE
will calladjustAxisLabelMargins()
to adjust the margins to ensure the labels will fit in the plot device size.adjustAxisLabelMargins()
was updated to handlepar("cex")
andpar("cex.axis")
appropriately.
sdim()
andssdim()
now handle environment input, or list of environments. Previously worked forsdim()
but using random order returned bynames(x)
instead of proper order fromls(envir=x)
. An environment is essentially treated as a list, andssdim()
will now properly traverse into the environment as if it were a list.sdim()
andssdim()
now handle"List"
object classes and sub-classes from theS4Vectors
Bioconductor package, but it only works when theS4Vectors
package is previously loaded into the search path, otherwise the R object object system does not load the dependent package automatically. In that case, theslotNames(x)
are used, which is somewhat less useful.imageDefault()
now properly honors thepar("bty")
setting, that is by not calling its ownbox()
to force drawing a box around the heatmap.
make_styles()
fixed issue with background color supplied in vector form, it was errantly callingfixYellow()
with the logical vector of whether to colorize, instead of the color vector itself. This package needs"testthat"
.
printDebug()
now handles nested lists, callingjamba::unnestList()
which flattens nested lists to one layer. This change allows printing a listprintDebug(c("one", "two "), c("three", "four"))
orl <- list(c("one", "two "), c("three", "four"));printDebug(l);
.printDebug()
now usescolor2gradient()
to create alternating light-dark shadings, used when a single color is defined for a multi-item vector concatenated bysep=","
. The gradient was more reliable (so far) thanmakeColorDarker()
because ANSI output is limited, as are the colors allowed for contrast with light or dark background.printDebug()
new argumenthtmlOut=TRUE
will output character string containing text colorized using HTML using the format<span style="color:red;background=white">text</span>
. Intended whenever the colorized text would not otherwise be interpreted and colorized in a web browser context. It callsmake_html_styles()
.make_html_styles()
is a new function, which takes a vector of text, a vector of foreground colors, a vector of background colors, and returns a character string with HTML which colorizes the text. This function is intended for Rmarkdown or web page HTML output.jargs()
was updated to handle arguments with vectors containing negative numbers. The negative-
sign for example from-3
is being returned byformals()
ascall(\\
-\, 3)
, which stores the numeric value separate from the negative sign. This seems like a change, which therefore broke how the colorization previously worked. For now the function works, but somehow lost the ability to colorize numeric vectors by value. Will leave for future.
pasteByRow()
properly handles leading blanks, it previously only correctly handled blank values in the second and subsequent columns. Caused by trying to simplify the R function when moving into the jamba package.
plotPolygonDensity()
new argumenthighlightPoints
allows highlighting points in the distribution, which is currently displayed as histogram bars on top of the histogram and density polygon fill. Also slight change to how the polygon density is sized, it uses the median ratio of the height of the density curve to the histogram bars at the center of each bar.
drawLabels()
first argument istxt
which is the label to be displayed, a small convenience change.breaksByVectors()
examples were updated to fix a typo when callingadjustAxisLabelMargins()
.- Added substantial content to the vignette, including moving
multiple images to
docs/articles
for pkgdown.
cPaste()
defaultdoSort=TRUE
is changed todoSort=FALSE
. New functions:cPasteS()
is intended for sorted values;cPasteU()
is an alias forcPasteUnique()
and is intended for unique values;cPasteSU()
is intended for sorted unique values. They all callcPaste()
but with convenience defaults. It is recommended to usecPasteS()
to replace sortedcPaste()
in cases where output is expected to be sorted. The change was made now while impact is limited mostly to other Jam packages and could be mitigated.
groupedAxis()
draws grouped axis labels, a small convenience function that extendsbreaksByVectors()
.
- Fixed regression in
provigrep()
when input is not character, the use ofmake.unique()
requires explicit conversion to character type first.
provigrep()
was enhanced to handle duplicated input entries, which previously returned only the unique entries, but now correctly returns all entries including duplicates, in the proper order. The optional list output also makes each list element unique. New argumentvalue
allows returning index positions, which is equivalent toproigrep()
. Lastly, theignore.case
argument is now properly honored, in order to allow case-sensitive matching.checkLightMode()
will not try to userstudio::getThemeInfo()
if that package is installed, and if the function API exists, in order to determine whether Rstudio is currently using a dark theme.make_styles()
has a new optional argumentbg_style
which allows defining the foregroundstyle
and backgroundbg_style
in one step. Whenbg_style
is supplied, the Crange and Lrange arguments are ignored. Fixed a bug when rendering in Rstudio, where an ANSI foreground color of white does not get properly reset, causing all subsequent foreground colors to be white despite clear ANSI codes for different colors. The workaround is to render white as slightly off-white (greyscale 254 instead of 255) which restores correct output.printDebug()
was enhanced to use thebg_style
argument ofmake_styles()
. New argumentinvert
which will switch foreground and background colors. Fixed some follow-up issues with handling empty strings.cPaste()
fixed issue withcPaste(NULL)
andcPaste(list(NULL))
which previously caused an error, now returns""
consistent with output fromcPaste(list(NULL, letters[1:2]))
where NULL entries produce""
.fixYellow()
new argumentfixup
passed tohcl2col()
which fixes out of gamut colors to scale within viewable range.writeOpenxlsx()
was not properly saving rownames with argumentkeepRownames=TRUE
, this issue was resolved.
- Fixed a typo in
make_styles()
where the default Lrange wasgetOption("jam.Crange")
instead ofgetOption("jam.Lrange")
. The affect is limited to debugging output when printed on a dark background. asSize()
was updated to handleobject_size
above 2.1e9 (2 Gigabytes), it previously converted to integer which does not handle values that large, but now converts to numeric.
log2signed()
performs log2 transformation of the magnitude of the numeric values, while preserving the directionality. It effectively performslog1p(abs(x))*sign(x)
except that by default it uses log base 2.exp2signed()
is the reciprocal tolog2signed()
, it exponentiates the magnitude of the numeric values, while preserving the directionality.
- Cleaned up unnecessary verbose output from
minorLogTicks()
.
- Fixed embarrassing type in R package dependencies, "S4Vector" instead of "S4Vectors".
setTextContrastColor()
default hclCutoff was changed from 73 to 60, in order to use dark text more often for the "in between" colors.makeNames()
now usesduplicated()
to detect duplicates prior to assigning names, which is substantially faster for long vectors where not all entries are duplicated, when compared to applyingtable(x)
to the entire vector. For large vectors with mostly duplicated values, the speed is the same as before. Note this change also affectsnameVector()
.sdim()
now handles a special case of S4 object where data is stored in one slot with slotName".Data"
, for example"limma::MArrayLM-class"
uses this format. When the length ofnames(x)
matches the length ofslot(x, ".Data")
then those names are applied.sclass()
now properly detects S4 objects, and specifically recognizesdata.frame
as a list even though it secretly hasslotNames
like an S4 object, while not being an S4 object. (Is it?) Matrix-like objects return the class of each column for consistency, even though all columns have identical class. This function also handles the same special case S4 scenario when it has only one slotName".Data"
, as described above forsdim()
.
-
mixedOrder()
did not sort properly when any entry contained only"-"
dashes, this problem has been fixed. Previously "-" was potentially used to indicate negative numbers and therefore not treated as a blank value, inadvertently becomingNA
and disrupting the ordering. Now strings"-"
and"---"
are considered blanks. -
mixedOrder()
now uses the input string as a final tiebreaker, so blank strings like"--"
and"-"
will also be sortedc("-", "--")
in the output instead of returning in the same order as the input. -
mixedOrder()
, several regular expressions were updated to cover edge cases, and will soon be wrapped into a series of"testthat"
unit tests, long overdue. Also, verbose output was slightly updated. Specifically:- blanks are properly ordered at the front when
blanksFirst=TRUE
, and at the end whenblanksFirst=FALSE
. - NA values are also properly ordered at the front and end
with
NAlast=FALSE
andNAlast=TRUE
respectively. The NA order has priority over blanks, so NA will always be completely first or completely last. - Infinite values, when
keepInfinite=TRUE
will be ordered at the end, but before blanks, then before NA values, if those values are also positioned at the end. Also, whenkeepNegative=TRUE
then"-Inf"
will be position at the beginning, but after NA then after blanks, if those values are also positioned at the beginning. keepNegative=TRUE
also enables recognition of scientific notation, but that regular expression wrongly allowed decimal exponentials, which is not valid (e.g. "1.23e1.2" is not valid.) now the exponential only includes non-decimal numeric values, e.g."-1.23e2.2"
is effectively considered"-1.23e2"
and"2"
.
- blanks are properly ordered at the front when
-
mixedSort()
,mixedSorts()
andmixedSortDF()
are all affected by the changes tomixedOrder()
. -
mixedSorts()
was updated to enable correct behavior whensortByName=TRUE
, which only works when all vectors in the input list are named. -
mixedSorts()
will accept nested lists, and would have used the ultra-coolutils::relist()
function, except that function does not allow re-ordering the vector names within the nested list. So a new functionrelist_named()
was added to jamba. It also works withsortByName=TRUE
to sort each vector by its names, by only if all vectors are named.
relist_named()
is a small modification of theutils::relist()
generic function (actually mostly just theutils:::relist.default()
). This function splits a vector into a list matching the structure of a skeleton list, except that the names of each vector in the output list will match the input vectorx
and not the names from the vectors in the skeleton list.
cPaste()
now properly handles a list with factor and non-factor types, previouslybase::unlist()
coerced the mixed list to character which changed factor values to integers when non-factor elements were present. NowkeepFactors=TRUE
will preserve factor levels when sorting withdoSort=TRUE
.
gsubOrdered()
appliesbase::gsub()
to character or factor input, and returns a factor output, retaining the order of levels based upon the input.
jargs()
changed the defaultsortVars=FALSE
which prints function arguments in the order they are defined.
mergeAllXY()
merges multiple data.frames, keeping all rows and columns.unnestList()
flattens a nested list-of-lists into a simple, flat list.
makeColorDarker()
fixed issue with repeated colors and darkFactors, processed using unique combination of color,darkFactor,sFactor to improve efficiency with large vectors, but was not properly handling the unique vectors.
- revised help text for
uniques()
col2hcl()
usescolorspace::sRGB()
instead ofcolorspace::RGB()
to match the convention thatcolorspace::hex2RGB()
actually uses sRGB and not RGB as the function name (and all common sense in the realm of how to name a function) implies.col2hcl()
andhcl2col()
allow selecting frompolarLUV
orpolarLAB
color models, both of which use HCL values to generate colors.col2hcl()
no longer forces the output vector to have names, however it retains names if provided in the input.hcl2col()
will usepolarLUV
orpolarLAB
as input without converting to an intermediate color space, which makes output slightly less lossy than converting to and from sRGB.
ucfirst()
is a simple function to uppercase the first letter in a word or phrase.mixedSorts()
will sort a list of vectors usingmixedSort()
alphanumeric sort, and fairly efficiently too! It sorts the unlisted data then splits it back to a list.drawLabels()
andcoordPresets()
were moved from thejamma
package. ThedrawLabels()
can be used to add text labels to a plot, with convenient coordinate presets handled bycoordPresets()
which include things like "topleft", "center", or "right". It automatically adjusts the text position to stay inside the plot border in those cases.
writeOpenxlsx()
is a wrapper for theopenxlsx
package, intended to encapsulate a large number of default options for certain "known" column data types, like P-values, log2 fold changes, and integer values.applyXlsxCategoricalFormat()
andapplyXlsxConditionalFormat()
to apply colors to an existing Excel xlsx file worksheet. These functions are called bywriteOpenxlsx()
but can also be called manually to customize an existing Excel file.
- Added "openxlsx" to Suggests.
asSize()
was updated to handle empty units, useful for numeric values especially when kiloSize=1000. Numbers are also trimmed throughformat()
independently so the number of digits is not propagated through all values.
setTextContrastColor()
has been updated to handle alpha transparency, semi-transparent colors are blended with the background color, then compared to the threshold.
formatInt()
is a quick wrapper function to format numeric values as integers, by default rounding decimal values and using big.mark=",", which can be overridden as needed.list2df()
to convert a list of vectors into a tall data.frame.
warpAroundZero() was not properly handling
baseline`, the method now uses a more straightforward approach.
- The site pkgdown documentation was updated to include each function in one (or sometimes multiple) categories, to help in finding potentially useful functions.
- The README.Rmd file has been stripped of the examples, which were a bit out of date compared to the function docs, and were not intended to be their own vignette. As I write this, I realize "removed visual examples" is rarely a positive step.
pasteByRowOrdered()
is an extension topasteByRow()
which creates an ordered factor, where the individual column order is maintained, either using existing factor level ordering, or viamixedSort()
per column.
unalpha()
simply removes the alpha transparency from an R hex color, which is required for some plotly functions for example.isTRUEV()
andisFALSEV()
are vectorized forms ofisTRUE()
andisFALSE()
. As they take vector input, the entire vector must belogical
in order for any entry to be considered.
rgb2col()
was enhanced so thealpha
argument conveys whether to return alpha transparency in the output string. It seemed to be a convenient place to control alpha since the conversion of color names to hex requires converting to RGB as an intermediate, then back to hex color.
minorLogTicks()
andminorLogTicksAxis()
had an argument renamed tooffset
instead oflabelValueOffset
. Better to change it now before it has wider use. Also, the defaults were changed tologBase=2
anddisplayBase=10
based upon the current most frequent usage. Best to set these values explicitly. Ideally, R graphical parameters should define the log base instead of TRUE/FALSE inpar("xlog")
andpar("ylog")
.normScale()
was modified so thelow
andhigh
range values are properly honored even when supplying a single value forx
. Now the behavior checks iflow
is equalhigh
to determine whether to use thelow
andhigh
values. This adjustment helpsapplyCLranges()
restrict colors to allowed ranges without over-correcting single colors to the midpoint of the range.
- Added function
sqrtAxis()
which computes axis tick mark positions for data that has been square root transformed, using transformationsqrt(abs(x))*sign(x)
in order to maintain positive and negative values. This function is called byplotPolygonDensity()
when usingxScale="sqrt"
.
- Cleaned up an issue with
getColorRamp()
with RColorBrewer colors, where it previously would retrieve colors using a number higher then the actual number supplied byRColorBrewer::brewer.pal()
, and which only issues a warning (which I had hidden.) The code now checks for the proper maximum number, and expands to the larger number usingcolorRampPalette()
as needed.
- Updated
cPaste()
to handle lists with a single NA value, which failed previously because a single NA is considered class "logical" and not "character" as required byS4Vectors::unstrsplit()
. - Changed how
Crange
andLrange
values are used inmake_styles()
, the new default will not overwrite the globalCrange
andLrange
settings. - Changed how
Crange
andLrange
values are enforced byapplyCLranges()
. There is a new argumentCLmethod
which controls how C and L values are adjusted.
fillBlanks()
is used to fill a vector that has missing values, and fills missing values with the most recent non-blank value. It is useful when importing Excel data where headings might be present in the first cell of a block of cells, followed by blanks.newestFile()
takes a vector of files, and returns the most recently modified, usingfile.info()
.
grepls()
a useful utility for search the active environment by object name. For examplegrepls("statshits")
will find everything named "statshits", orgrepls("farris")
will find everything with "farris" in the name", even within packages, or other attached environments in the search space.warpRamp()
takes a vector of colors as from a color gradient, and warps the gradient. For divergent colors, the adjustmet is symmetric around the middle color; otherwise the adjustment is relative to the first color. Helpful for adjusting colors scales in heatmaps.
imageDefault()
,plotSmoothScatter()
,smoothScatterJam()
were updated to allow values lower than 200 fornbin
which previously caused problems whenfixRasterRatio=TRUE
andoldstyle=TRUE
.rmNA()
by default returnsNULL
when givenNULL
input, unlessnullValue
is defined. This change fixed several warnings, and resolved inconsistencies withsetCLranges()
not handling NULL parameters properly, consequently affectingmake_styles()
ability to restrict the color chroma (C) and luminance (L) ranges, seen whenprintDebug()
did not use scaled colors.- Fixed bug in
hcl2col()
during detection of RGB values above 255, which sometimes happens during thecolorspace::polarLUV()
conversion from HCL to RGB.
rlengths()
returns the recursive lengths of list elements, intended when a list may have multiple nested lists. It returns the top level of counts per list element by default, but withdoSum=FALSE
it returns the full structure with the length of each non-list element.
minorLogTicksAxis()
andminorLogTicks()
provide log-transformed axis labels, with the added benefit of handlinglog(1+x)
transformations properly; or log2FoldChange data with symmetry around zero.renameColumn()
a basic function but which allows re-running the function without error.normScale()
scales a numeric vector into a fixed range, by default between 0 and 1. If one value is given, a parametersingletMethod
defines whether to use the minimum, maximum, or mean of the range.rowGroupMeans()
androwRmMadOutliers()
are used to compute per-row mean values, with grouped columns. Optional outlier detection is performed using a MAD factor cutoff, for example 5xMAD threshold means points 5 times the MAD for the group are considered outliers.plotPolygonDensity()
which is a wrapper aroundhist()
andplot(density(x))
, but with some added features like scaling the x-axis by log10 or sqrt; and multi-panel output when the input is a multi-column matrix.warpAroundZero()
takes a numeric vector, and warps the values with a log curvature, symmetric around zero. The intent is to create non-linear breaks when used in heatmaps with divergent color ramps.
ssdim()
was updated again to try to handle more non-list object types, for example the "bga" class returned from made4::bga().
- Fixed small issue with R docs that did not properly wrap the
%>%
inside\code{\%>\%}
blocks, which allows the percent sign to be escaped and ignored. - Fixed numerous incorrectly formatted
\code{\link{}}
sections which did not properly specify the package name. The issue apparently only causes errors during package install on systems using HTML as the preferred help format.
smoothScatterJam()
andimageDefault()
were updated to fix edge cases where the image being rendered was expected to have integer axis units, but where the raster ratio had duplicated columns or rows, making the units imprecise.setPrompt()
has defaultprojectName=NULL
instead of trying to pull fromprojectName
from the.GlobalEnv
environment, which would cause an error if not defined. Instead, ifNULL
then it checks ifprojectName
exists, if so the value is used.
- Fixed issue with
sdim()
so it would properly traverse a non-vector and non-list object which may contain elements with length or dimension.
setCLranges()
was adjusted to use global options where available, and by default will update global options when not defined. This mechanism allows one to set specific Crange and Lrange values, and have them be re-used by functions affected by those values.ssdim()
now handles S4 objects by iterating each slotName and callingsdim()
.sdim()
now properly handles detection of S4 classes.
fixYellowHue()
takes a matrix of HCL colors (as fromcol2hcl()
) and adjusts colors between hue 80 and 90 so they appear less green. This change is a visual preference that the default yellow appears green when darkened, and simply makes the color appear less green.fixYellowColor()
takes a vector of colors as a wrapper tofixYellowHue()
.
The main change in this version was to reduce required R version to 3.0.0.
cPaste()
is an efficient method of pasting a list of vectors using a delimiter, to create a character vector. It usesmixedOrder()
to sort entries, and optionally applies uniqueness to the vectors.uniques()
takes a list and makes each vector in the list unique, using an efficient mechanism that applies uniqueness to the overall set of values at once.
- The Bioconductor package
S4Vectors
implements efficientunstrsplit()
used bycPaste()
. However, S4Vectors therefore requires installing Bioconductor base packages, which might be a heavy installation requirement just for improved efficiency at this step. In future this one function may be reproduced here (with permission of author Dr. Pages) to reduce the dependency burden.
jargs()
does a better job of handling functions with nested lists, and closes any open[
with corresponding]
.jargs()
properly honorsuseColor=FALSE
to disable colorized text, and addscolNULL
to assign a color forNULL
values, by default grey.printDebug()
,make_styles()
will apply a CL range, chroma (C) and luminance (L) values, which are defined in part bylightMode
and corresponding functioncheckLightMode()
, and a helper functionsetCLranges()
which sets sensible default values for light and dark backgrounds.printDebug()
has two optional parametersCrange
andLrange
which define a chroma (C) range and luminance (L) range. For lighter background, a maximum luminance of 80 seems reasonable; for darker background colors, minimum luminance of 75 is effective. The only awkwardness is that yellow darkens to a greenish hue, which is not aesthetically pleasing, so because I even noticed it, I had to "fix" the issue by adjusting yellows to more gold before darkening, enabled with default argumentfixYellow=TRUE
.make_styles()
callsapplyCLrange()
which fixes the chroma (C) and luminance (L) values, hopefully to sensible default values.
applyCLrange()
takes a vector of colors, and fixes the chroma (C) and luminance (L) values to this range. IfCgrey
is above zero, then colors with chroma (C) value below this threshold are kept unchanged, in order to prevent a purely grey (unsaturated) color from becoming colorized.setCLranges()
will querycheckLightMode()
and returnCrange
andLrange
default values.hcl2col()
which simply converts the output ofcol2hcl()
back to a vector of R hex colors. It should not be lossy, meaning it should faithfully convert R colors to an HCL matrix, then back to the same R original hex colors. Alpha transparency is also maintained. Note thathcl2col()
performs differently thangrDevices::hcl()
which does not produce the same colors ascolorspace::polarLUV(H, C, L)
using the same values forH
,C
, andL
. The reasons unclear, however the functions injamba
are internally consistent, usingcolorspace
functions.
- jamba now uses some global options(), intended only for function parameters
that affect visual output, and will not affect analysis processing.
Examples:
jam.adjustRgb
- numeric, sets the parameter "adjustRgb
" in printDebug().jam.lightMode
- boolean, sets the lightMode, see below.
printDebug()
has a new boolean parameter "lightMode", which is TRUE when the background color is light (e.g. white or light-grey.) In this case, it applies a ceiling to the brightness of all text colors to ensure none are too bright to be visible.mixedSortDF()
now accepts character values forbyCols
, with optional prefix "-" to indicate decreasing sort. Alternatively, the parameter decreasing will still be used to reverse the sort, and is converted to a vector when byCols has multiple values. Note that the prefix "-" and decreasing are multiplied to combine them.smoothScatterJam()
tests if postPlotHook is a function, in which case it runspostPlotHook(...)
otherwise it simply evaluatespostPlotHook;
nullPlot()
,usrBox()
, andimageDefault()
have a new boolen parameter "add
" indicating whether to create a new plot or add to an existing plot device.rbindList()
has a new boolean parameterkeepNA
indicating whether to keep NA values in the results, which ultimately causes NA to be converted to "NA".makeNames()
has a new boolean parameterkeepNA
indicating whether to keep NA values in the results. When keepNA is TRUE, NA is converted to "NA", otherwise NA entries are treated as "" prior to creating names.rmNA()
changed the default value for parameterrmNAnames
toFALSE
, which was the more anticipated behavior. An input vector will not be shortened for non-NA values that have an NA name. Changing function parameter defaults will be an extremely rare occurrence in future.make_styles()
which is a vectorized wrapper forcrayon::make_style()
, gains some finer control over color chroma and luminance.jargs()
gets a larger refactoring, aimed at better display of list parameters, and lists of lists and other nested variations. It now does a better job of displaying the list and vector names appropriately. A new functionhandleArgsText()
was split into a separate function, but is a rare non-exported function since it is currently only useful forjargs()
.- TODO.md was created to keep track of future enhancements and fixes.
applyLceiling()
intended to restrict colors to a maximum luminance in HCL color space, mainly to support the new lightMode option intended for usingprintDebug()
with a light background.checkLightMode()
intends to support the new lightMode option by doing its best to check situations to enable lightMode. It first checks options("lightMode"). It then checks environment variables that suggest Rstudio is running, in which case it defaults to lightMode=TRUE, since the default Rstudio has a light background.sclass()
,sdim()
, andssdim()
are intended to help handle list objects.sclass()
returns the class of each list element.sdim()
returns the dimensions (or lengths) or each list element.ssdim()
is a special case that returns the dimensions of a list of list of objects. In all cases, if the input object is an S4 object, it operates onslotNames(x)
. Thus, callingssdim(x)
is helpful for S4 objects, since it returns the class and dimensions of each object inside the S4 object.