rcicr 1.2.2
This release exists to answer the changes CRAN asked for when reviewing the previous
submission. Nothing it changes affects a number this package computes: classification
images, scaling, z-maps and informational value are identical to 1.2.1, and the release
gate confirms that against both 1.2.1 and 1.0.1.
Breaking changes
-
Functions that write files now require you to say where.
stimulus_path
(generateStimuli2IFC()),targetpath(generateCI(),generateCI2IFC(),
batchGenerateCI(),batchGenerateCI2IFC(),autoscale(),plotZmap()) and
zmaptargetpath(generateCI()) have lost their defaults. They used to be./stimuli,
./cisand./zmaps, which meant a default call created directories in whatever your
working directory happened to be — writing to your filespace without being asked, which
CRAN policy does not permit.What to change in your scripts. If you relied on the old defaults, name them:
# before generateCI(stimuli, responses, "face", rdata) # after generateCI(stimuli, responses, "face", rdata, targetpath = "./cis")
You will not silently get files somewhere new — a call that would have written to a
default path now stops with an error naming the argument to supply. If you do not want
files at all,save_as_png = FALSE(orsave_as_pngs = FALSEforautoscale()) needs
no path.
Bug fixes
-
batchGenerateCI()no longer produces a spurious CI for rows with no group. Rows
whosebycolumn wasNAwere kept and collapsed into an extra group named afterNA,
so a data frame with any missing grouping value returned one more classification image
than it had groups — computed from whatever rows happened to be missing that value.
batchGenerateCI2IFC()has always dropped those rows; the two now agree. -
generateCI(mask = )accepts a logical matrix. The matrix branch tested
typeof(mask) == 'double', so a mask built the obvious way — asTRUE/FALSErather
than1/0— fell through toThe mask argument is neither a string nor a matrix!,
despite the documentation describing exactly that form. It is now tested with
is.matrix(). -
generateCI()andcomputeCumulativeCICorrelation()no longer print the entire base
image when they cannot find stimulus parameters. The "No parameters found for base image"
error named the base image matrix where its label was meant. Becausepaste0()is
vectorized, this did not paste one matrix into one message — it built one complete message
per pixel, so the error came back as 1,024 concatenated copies at a 32x32 base image (8,190
characters) and roughly 7 MB at the 512x512 size researchers actually use, with the reason
for the failure buried inside it. The message now reads, in full,No parameters found for base image: <label>.Only the text of an error changed. No function's return value, arguments or numeric output
are affected, and the condition that triggers the error is unchanged — if your analysis
script runs today, it behaves identically. -
generateReferenceDistribution2IFC()no longer leaves a straystimulidirectory
behind. It re-derives the noise basis by callinggenerateStimuli2IFC()with both save
options off, purely to work in memory — but the directory was created before either
option was consulted, so every call to it, and tocomputeInfoVal2IFC()when no
reference distribution was cached, created an empty./stimuliwherever you happened to
be working.BACKLOG.mditem 24. -
plotZmap()restores the graphics parameters it changes. The undecorated branch set
par(mar = ...)and left it set. It also now closes its PNG device throughon.exit(),
so a failure part-way through plotting can no longer leak the device or leave a
half-written file.
Documentation
-
The
DESCRIPTIONdescription no longer opens with the redundant "Functions to", and
cites the two method references: Dotsch and Todorov (2012)
doi:10.1177/1948550611430272 and Brinkman, Todorov and Dotsch (2017)
doi:10.1080/10463283.2017.1381469. -
Every example runs. The
\donttest{}wrappers are gone from all eight examples that
carried them,simulateNoiseIntensities()'s\dontrun{}is gone, and
generateNoiseImage()'s example is real code rather than three commented-out lines that
would not have worked (pwas never defined, andparamswas the wrong length for the
pattern). The whole example set now runs in about nine seconds. -
simulateNoiseIntensities()'s note claiming the function always errors is removed. It
described two bugs that were fixed in 1.1.0; the note was left behind.
Internal
-
Bare
TandFare replaced byTRUEandFALSEthroughoutR/. Two of these were
public API defaults visible in the documentation (generateCI(zmap =, zmapdecoration =)
andplotZmap(decoration =)); the values are unchanged. -
The guard that keeps a function's arguments across
load()is now a shared helper,
captureArgs(). It skips required arguments that were not supplied — necessary once
paths became required, sincemget()forces the promise and a wrapper forwarding its own
missing argument would abort there. Defaulted arguments are still captured:missing()
reports those missing too, and their default is exactly as vulnerable to being replaced
by a field in the.Rdatafile as a value passed explicitly. -
The failure paths are tested. The suite had 9 assertions covering 33
stop()and
warning()calls, so most of the package's error messages had never been run. They now
are: the stimuli/responses length mismatch, every "this.Rdatafile did not contain X"
guard ingenerateCI()andcomputeCumulativeCICorrelation(), all four mask-import
failures, and base images that are unreadable or not square. No behaviour changed — this
is coverage of messages that were already there. It matters because an unexercised guard
is indistinguishable from one that works, which is how three separate bugs in this package
stayed live for years, the most recent being the one fixed just above. -
Every function that reads a stimulus set now keeps its arguments across the
load().load()assigns straight into the calling function's frame, so an object
stored in an.Rdatafile silently replaces an argument of the same name.generateCI()
andgenerateReferenceDistribution2IFC()already guarded against this;computeInfoVal2IFC()
guarded three of its five arguments, andcomputeCumulativeCICorrelation()none.No file this package has ever written triggers the problem, so no result changes and
no analysis needs revisiting — the guard is preventive. It is worth having because the one
collision that did occur (the z-mapsigma, fixed in 1.2.0) was created by adding a field
to the file, not by adding an argument, so an argument that is safe today stops being safe
without anything in the function changing. The case now closed incomputeInfoVal2IFC()is
the one that would have mattered most:target_ciis read at the very end to compute the
CI norm, and after a secondload(), so a file carrying that name would have scored a
different classification image and returned a plausible number rather than an error.