Pavel N. Krivitsky
krivitsky.net
Pavel N. Krivitsky
@krivitsky.net
Inveterate 🕸 modeller
𝑃(🦋; 𝜽) = 𝘩(🦋) exp{𝜼(𝜽) · 𝒔(🦋)} / 𝜅(𝜽)
👨🏻‍🏫 Statistics at UNSW 🇦🇺
👨🏻‍💻 10 #RStats 📦
ex-🪑 @ANSNA.org.au

https://krivitsky.net
https://statnet.org
https://github.com/krivit
For those building on top of {ergm}, there is now an experimental C++ shim (wrappers around C structs) for implementing ERGM statistics and proposals using idiomatic C++. Check out the vignette (cran.r-project.org/package=ergm...). This was easier than I had expected, thanks to coding AIs.
A C++ shim for ergm
cran.r-project.org
December 30, 2025 at 1:56 AM
For advanced users, there is a ChangeStats(formula) constraint, which rejects all proposals that change the value of the specified statistics and operator I(x) that substitutes ERGM formula x or initialised model into its formula, it easier to assemble complex formulas out of smaller components.
December 30, 2025 at 1:56 AM
Also, the Sampson's monks datasets included with the package have been cleaned up and augmented; in particular, they now include the scores (+3, +2, etc.) and the dislike networks as well (though granted, it is not clear which of those were contemporaneous as opposed to retrospective).
December 30, 2025 at 1:56 AM
A time-saver for those fitting models with many different terms: nonidentifiability/multicollinearity detection code now tries to figure out precisely which statistics are linearly dependent on which and pretty-prints the result.
December 30, 2025 at 1:56 AM
The gof() family of functions now supports valued ERGMs. This has been a long-requested feature, and it's finally here. The only built-in statistic is the empirical CDF of edge values, but you can also now put any statistic on the GOF formula, even if it won't be as pretty.
December 30, 2025 at 1:56 AM
So, this is what the typical first line would look like:

sim <- piecemeal::Piecemeal$new(dir)

or

sim <- Piecemeal::Piecemeal$new(dir)

Thoughts?
September 12, 2025 at 7:05 AM
Getting this ready for #CRAN, a quick poll: should I call it {piecemeal} or {Piecemeal}? It's basically one #R6 class, `Piecemeal`, e.g.,

sim <- Piecemeal$new(tmpdir) # Initialise
sim$worker(f)$nrep(5)$ etc. # Set up
sim$run() # Execute
results <- sim$result_df() # Collate
September 12, 2025 at 7:05 AM
krivitsky.net/sunbelt2025/ is now linked from sunbelt2025.org by @sunbelt2025paris.bsky.social l . Double-checking the code now... 😅
June 26, 2025 at 6:34 AM
This list is based on the PDF you can export from Whova, which I hopefully parsed correctly. It is in no way endorsed by @insna.bsky.social or @sunbelt2025paris.bsky.social 's organisers. I will strive to keep it up to date throughout the conference, but the updates are not automatic.
June 25, 2025 at 1:46 PM
There are also more utilities for PSD matrix calculations, particularly for computing xᵀV⁻¹x, taking into account that:

* base::solve() treats diag(c(1e10, 1e-10)) as computationally singular.

* Even when V is, in fact, singular, a unique and sensible answer still exists if x is in the span of V.
May 30, 2025 at 11:13 AM
A helper function modify_in_place() for easily implementing functions that robustly modify their arguments in place (without resorting to environments a la #R6). E.g.,

> inc <- function(x){
modify_in_place(x, x+1)
}
> x <- 1:3
inc(x[1])
> x
[1] 2 2 3
May 30, 2025 at 11:13 AM
New functions include statnet.common::replace(x, list, values) a drop-in replacement for the {base} function that can take function arguments for list= and values= so that, e.g.,

x |> replace(is.na, 0)

does exactly what you would want it to, as does `replace<-`, for

replace(x, is.na) <- 0

.
May 30, 2025 at 11:13 AM
Granted #Bioconductor 's S4Vectors::Rle() almost certainly does everything that {rle} does but better, but it also means depending on Bioconductor. Is it no longer the hassle that it used to be?
May 30, 2025 at 1:29 AM
This is really cool! I've been using US election maps to illustrate the point in my Data Viz class, but I suppose it's long past time to localise.
May 4, 2025 at 12:59 PM