num2str sets a constant width for integer formatting - string

I am using num2str to print an array of integers. My problem is that the format %d, (notice no flag or field width) doesn't yield a comma-separated list of values as I would expect.
Instead, it seems that all elements are forced to the same width by introducing spaces. I would like to get rid of these spaces. For example:
>> num2str(randi(10,1,10),'%d,')
7, 8,10,10, 2, 2, 7, 1, 6, 6,
>> num2str(randi(10,1,10),'%d,')
9,5,4,7,8,6,4,2,6,3,
In the first example, you can see that all elements have a width of 2 -- this is the largest width among all elements, but I would prefer the output list to be compact: 7,8,10,10,2,2,7,1,6,6,. In the second example, the largest width is 1, and there are no spaces introduced. I don't understand why Matlab would force all elements to have equal field length.

num2str computes the max of the vector, and pads with white space numbers that have less digits (type edit num2str in the command window to see the source code).
Try sprintf instead,
sprintf('%d,', randi(1000,1,10))

Related

Significant figures for mean and sds in forest plot for metafor

I created a forest plot using metafor. The data I downloaded all has two significant figures after the decimal point for the study means and SDs, but when it uploads to the forest plot, these trailing zeros are dropped.
How can I keep these trailing zeros to make it look better?
The code for the forest plot is:
forest(meta2, showweights = TRUE, ilab.xpos=c(-24.5,-22, -19.5, -16, -13.75, -11),
ilab=cbind(bmi_awm$Intervention_n, bmi_awm$Intervention_mean, bmi_awm$Intervention_SD, bmi_awm$Comparison_n, bmi_awm$Comparison_mean, bmi_awm$Comparison_SD),(digits=2),
ilab.pos = 4,
rows=c(48), ylim=c(-1, 51.5), xlim=c(-35.5, 14), at=(c(-7, 0, 7))
enter image description here
See the documentation of the forest() function:
https://wviechtb.github.io/metafor/reference/forest.rma.html
digits: integer to specify the number of decimal places to which the tick mark labels of the x-axis and the annotations should be rounded (the default is 2L). Can also be a vector of two integers, the first to specify the number of decimal places for the annotations, the second for the x-axis labels. When specifying an integer (e.g., 2L), trailing zeros after the decimal mark are dropped for the x-axis labels. When specifying a numeric value (e.g., 2), trailing zeros are retained.
The problem in your code is that you have digits=2 wrapped in parentheses. Get rid of those and the training zeros should be retained.

Web Assembly drawing gray canvas

I'm using Go and compiling it to web assembly.
I'm trying to render a bunch of rectangles next to eachother with a random colour, but they keep rendering as just gray.
My render function looks something like this:
for row,_ := range rows {
for col,_ := range row {
ctx.Set("fillStyle", fmt.Sprintf("#%06x", rand.Int()))
ctx.Call("fillRect", 20, 20 + (col * width), maxHeight - (row*height))
}
}
With which it renders a big block (all rectangles are next to eachother) but just all in gray, instead of doing them in different colours.
Is this enough code in the example to help further? If not I can post it to a gist, as I'm new to WASM I'm unsure which parts could really be relevant - but those 2 functions are the only ones doing something with rendering as far as I can tell.
The problem is that you use this expression to construct the fill style:
fmt.Sprintf("#%06x", rand.Int())
rand.Int() returns a non-negative pseudo-random int. Size of int is 64 bits if GOOS=js and GOARCH=wasm. What this means is that the random int number will be random 8 bytes (first bit being always 0 due to being non-negative).
If you format such a number with the %06x verb, like almost all the time it will be more than just 6 hex digits. The width 6 means to be at least 6, and the flag 0 means to pad with zeros if less. But if it's longer, it is not truncated.
And if you set an invalid color to canvas.fillStyle, it will disregard it and the last set valid fill style will remain active. And I'm guessing it was a gray color you used before the loop.
Fix is easy, just make sure the random number has no more than 3 bytes, or in other words, 6 hex digits. Use a simple bitmask:
ctx.Set("fillStyle", fmt.Sprintf("#%06x", rand.Int()&0xffffff))
Or use rand.Intn() instead of rand.Int():
ctx.Set("fillStyle", fmt.Sprintf("#%06x", rand.Int(0x1000000)))
Also context.fillRect() expects 4 arguments: x, y, width and height, so it should be something like this:
ctx.Call("fillRect", 20+(col*width), maxHeight-(row*height), width, height)

Generate strings which have normal distribution length (Matlab)

I have an initial string : S= 'ABCDEFGH'
How can I generate 100 strings from S where there is no repeated character in each string and the characters in each string will be in an order from 'A' to 'H' . Every string has diffent length which is based on normal distribution.Here, the mean=4, and sd = 1
The expected output (may be different because of random strings are genrated should be 100 srings like below:
Output = { 'ABEGH'; 'ABE'; 'DH' ; 'BCGH' ..........; 'ABCDEGH'}
Thanks !
It's not clear what distribution you want. This is a generic answer for any length distribution.
S = 'ABCDEFGH'; %// input characters
distr = [.1 .2 .1 .2 .1 .1 .1 .1]; %// probability of getting lengths 1, 2, ..., numel(S)
n = randsample(numel(distr), 1, 1, distr); %// random length with the specified distribution
ind = sort(randperm(numel(S), n)); %// take n sorted values from 1, ..., numel(S);
result = S(ind);
Assuming all permutations produced from randperm are equally likely1 the above code, conditioned on a given n, generates all possible n-digit substrings with the same probability.
1
In old Matlab versions randperm was an m-function. From its source code it was clear that it produced all permutations with the same probability. In recent versions it's not an m-function anymore, and its documentation doesn't specify that.

List of ints to list of strings in MATLAB

I have a list of integers
[0, 10, 20, 30, ...]
And I want to use them as a legend in a plot. My understanding is that I need to give the command
legend('0','10','20','30', ...)
So how do I get a list of strings from my original vector to pass to legend()?
num2str isn't working for me because I get just one long string. I'm still a little new to MATLAB syntax...
legend(num2str([0, 10, 20, 30]'))
Converting a column vector of numbers will produce a char array with m rows, where each row can be a legend entry.

Avoid & Count non-numerical values computing basic statistics in Mathematica

Please consider:
dalist={{1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
{2.88`, 2.04`, 4.64`,0.56`, 4.92`, 2.06`, 3.46`, 2.68`, 2.72`,0.820},
{"Laura1", "Laura1", "Laura1", "Laura1", "Laura1",
"Laura1", "Laura1", "Laura1", "Laura1","Laura1"},
{"RIGHT", 0, 1, 15.1`, 0.36`, 505, 20.059375`,15.178125`, ".", "."}}
The actual dataset is about 6 000 rows and 147 columns. However the above reflects its content. I would like to compute some basic statistics, such as the mean. My attempt:
Table[Mean#dalist[[colNO]], {colNO, 1, 4}]
How could I create a function such as to:
Avoid non-numerical values and
Count the number of non numerical values found in each lists.
I have not succeeded in finding the right pattern mechanism yet.
First observation: you could use Mean /# dalist if you wanted to average across rows. You don't need a Table function here.
Try using Cases (documentation), eg. Mean /# (Cases[#,_?NumericQ] & /# dalist)
If you want to be tricky and eliminate rows from your data that have no numeric elements (eg your third column), try the following. It first picks only the rows that have some numeric elements, and then takes only the numeric elements from those rows.
Mean /# (Cases[#,_?NumericQ] & /# (Cases[dalist, {___,_?NumericQ,___}]))
To count the non-numeric elements, you would use a similar approach:
Length /# (Cases[#,Except[_?NumericQ]] & /# dalist)
This answer has the caveat that I typed it out without the benefit of a Mathematica installation to actually check my syntax. Some typos could remeain.
Here is a variation of Verbeia's answer that you may consider.
Assuming that this is a rectangular array (all rows are the same length), then setting d to the row length (which can be found with Dimensions):
d = 10;
{d - Length##, Mean##} &#Select[#, NumericQ] & /# dalist
(* Out: *) {{0, 11/2}, {0, 2.678}, {10, Mean[{}]}, {3, 79.5282}}
That is, pairs of {number_of_non-numeric, average}.
Mean[{}] appears where there are no numeric values to average. This could be removed from the list with DeleteCases but the results would no longer align with the rows of dalist. I think it would be better to use something like: /. Mean[{}] -> "NO AVERAGE" if needed.
The key to answering your question is the NumberQ function: "*NumberQ[expr] gives True if expr is a number, and False otherwise."
To compute the mean of only numeric elements in each list:
Map[Function[lst, Mean[Select[lst, NumberQ]]], dalist]
To count the number of non-numeric elements in each list:
Map[Function[lst, Length[Select[lst, Function[x, !NumberQ[x]]]]], dalist]

Resources