I want to print entries of a matrix using formatted printing. Specifically I'd like to use "]"
for the first column, and "%6.4f"
for the remaining columns. The issue I am running into is that I have an arbitrary number of "decimal" columns and (sensibly), sprintf
doesn't recycle its format string, e.g. sprintf("%6.4f", x[,1:4])
doesn't give you four columns of nicely printed numbers. I have some work arounds, but is there there something easier?
A reproducible example of what I would like to achieve:
set.seed(1234)
x = matrix(runif(20), ncol = 4)
x = cbind(1:5, x)
x = sprintf("] %6.4f %6.4f %6.4f %6.4f\n", x[,1], x[,2], x[,3], x[,4], x[,5])
cat("\n", x)
but the issue is that the dimension of x
changes from run to run. I could programatically build the format string, and the input string and use eval
and parse
, but this seems like overkill.
Please don't suggest that I use the digits
option of print
- it doesn't do what I want.
CodePudding user response:
Another option that yields the same results:
set.seed(1234)
x = matrix(runif(20), ncol = 4)
x = cbind(1:5, x)
cbind(
format(x[,1], digits = 0),
format(x[,2:ncol(x)], digits = 4)
) |>
apply(1, \(z) paste(c(" ", z, "\n"), collapse = " ")) |>
(\(w) cat("\n", w))()
#>
#> 1 0.113703 0.640311 0.693591 0.837296
#> 2 0.622299 0.009496 0.544975 0.286223
#> 3 0.609275 0.232551 0.282734 0.266821
#> 4 0.623379 0.666084 0.923433 0.186723
#> 5 0.860915 0.514251 0.292316 0.232226
CodePudding user response:
set.seed(1234)
x = matrix(runif(20), ncol = 4)
x = cbind(1:5, x)
fmt = do.call( sprintf, c(list(
paste("]", paste(rep("%6.4f",ncol(x)-1), collapse=" "),"\n")),
lapply(1:ncol(x), \(i) x[,i])))
cat("\n", fmt)
#>
#> 1 0.1137 0.6403 0.6936 0.8373
#> 2 0.6223 0.0095 0.5450 0.2862
#> 3 0.6093 0.2326 0.2827 0.2668
#> 4 0.6234 0.6661 0.9234 0.1867
#> 5 0.8609 0.5143 0.2923 0.2322
Try with another matrix dimensions
CodePudding user response:
This is much less elegant than the solutions above:
set.seed(1234)
x = matrix(runif(20), ncol = 4)
x = cbind(1:5, x)
numClusters = 4
printProbs = function(probs){
fmtString = paste0("M ",
paste0(rep(" %6.4f", numClusters), collapse = " "),
"\n")
inputsString = paste0("probs[, ", 1:(numClusters 1), "]", collapse = ", ")
cmd = paste0("sprintf(\"", fmtString, "\", ", inputsString, ")")
eval(parse(text = cmd))
}
cat(printProbs(x))
which yields:
> cat(printProbs(x))
1 0.1137 0.6403 0.6936 0.8373
2 0.6223 0.0095 0.5450 0.2862
3 0.6093 0.2326 0.2827 0.2668
4 0.6234 0.6661 0.9234 0.1867
5 0.8609 0.5143 0.2923 0.2322
I'm unsure why the first line skips a space, but I can fix this in code.