I can sample from a 1-D array just fine. E.g.
julia> a = [1; 2; 3]
3-element Array{Int64,1}:
1
2
3
julia> sample(a, myweights, 5)
5-element Array{Int64,1}:
1
2
1
3
3
I can also take weighted samples:
julia> myweights = weights([0.8, 0.1, 0.1])
StatsBase.WeightVec{Float64,Array{Float64,1}}([0.8,0.1,0.1],1.0)
julia> sample(a, myweights, 5)
5-element Array{Int64,1}:
2
1
1
1
1
I'd like to do the same thing for a 2D array, but sampling by row and not by element. E.g. if I have the array
julia> b = [1 1 1; 2 2 2; 3 3 3]
3×3 Array{Int64,2}:
1 1 1
2 2 2
3 3 3
I'd like to be able to take unweighted and weighted samples that give me outputs like
1 1 1
2 2 2
1 1 1
1 1 1
3 3 3
How can I do this?
The simplest solution here is to sample from the indices of the rows, and then use that to index into your matrix:
julia> idxs = sample(axes(b, 1), myweights, 10)
10-element Array{Int64,1}:
1
1
1
2
1
1
3
1
1
1
julia> b[idxs, :]
10×3 Array{Int64,2}:
1 1 1
1 1 1
1 1 1
2 2 2
1 1 1
1 1 1
3 3 3
1 1 1
1 1 1
1 1 1
Related
I have a matrix and I would like to know the center and min/max size of each cluster represented by the same number value.
By example, to get the center position and size of clusters (or the min/max column/row) represented by the number 2 in the following matrix. The idea is closed to the one perform on an image How to obtain size of cluster of pixels in R and How to obtain size of multi clusters in matrix (R)
But when I use the function apply(matrix2, 2, mean) and apply(matrix2, 2, range), results merge the two clusters. Is there a way to get each cluster ?
> matrix<- read.csv("2_ind_matrix.csv")
X1 X1.1 X1.2 X1.3 X1.4 X1.5
1 1 1 1 1 1 1
2 1 1 1 1 1 1
3 1 1 1 1 1 1
4 1 1 1 2 2 2
5 1 1 1 1 2 2
6 1 1 1 1 1 1
7 1 1 1 1 1 1
8 1 1 1 1 1 1
9 1 1 1 1 1 1
10 1 1 1 1 1 1
11 2 1 1 1 1 1
12 2 1 1 1 1 1
13 2 1 1 1 1 1
14 2 2 1 1 1 1
15 2 2 2 1 1 1
16 2 2 2 2 2 2
17 2 2 2 2 2 2
> matrix2<- which(matrix == 2, TRUE)
> apply(matrix2, 2, range) #Range
row col
[1,] 4 1
[2,] 17 6
> apply(matrix2, 2, mean) #Center
row col
13.16 3.20
The decision on how many clusters are there needs to be done. Here I assume there are 2 clusters. Those can be found by kmeans by using the positions returned from which.
y <- which(x==2, TRUE)
y <- cbind(y, cluster=kmeans(y, 2)$cluster)
aggregate(y[,1:2], list(y[,3]), range)
# Group.1 row.1 row.2 col.1 col.2
#1 1 4 5 4 6
#2 2 11 17 1 6
aggregate(y[,1:2], list(y[,3]), mean)
# Group.1 row col
#1 1 4.40 5.2
#2 2 15.35 2.7
I'm using Julia comprehension to achieve the following:
Given a matrix
A = [1 2; 3 4],
I want to expand it into
B =
[1, 1, 1, 2, 2;
1, 1, 1, 2, 2;
1, 1, 1, 2, 2;
3, 3, 3, 4, 4;
3, 3, 3, 4, 4].
Right now I'm doing this with
ns = [3, 2]
B = [fill(B[i, j], ns[i], ns[j]) for i = 1:2, j = 1:2]
However, instead of getting a 5x5 matrix, it gives me:
2×2 Array{Array{Int64,2},2}:
[0 0 0; 0 0 0; 0 0 0] [0 0; 0 0; 0 0]
[0 0 0; 0 0 0] [0 0; 0 0]
So how should I convert this 2d array of matrices to a 2d matrix? Or are there other ways to do the expansion I need?
Here are two example ways how you could do it (the first one uses your approach, the second one does not generate intermediate matrices):
julia> A = [1 2; 3 4]
2×2 Array{Int64,2}:
1 2
3 4
julia> ns = [3, 2]
2-element Array{Int64,1}:
3
2
julia> hvcat(2, [fill(A[j, i], ns[j], ns[i]) for i = 1:2, j = 1:2]...)
5×5 Array{Int64,2}:
1 1 1 2 2
1 1 1 2 2
1 1 1 2 2
3 3 3 4 4
3 3 3 4 4
julia> nsexpand = reduce(vcat, (fill(k, ns[k]) for k in axes(ns, 1)))
5-element Array{Int64,1}:
1
1
1
2
2
julia> [A[i, j] for i in nsexpand, j in nsexpand]
5×5 Array{Int64,2}:
1 1 1 2 2
1 1 1 2 2
1 1 1 2 2
3 3 3 4 4
3 3 3 4 4
EDIT
Here is an additional example:
julia> A = [1 4 7 10
2 5 8 11
3 6 9 12]
3×4 Array{Int64,2}:
1 4 7 10
2 5 8 11
3 6 9 12
julia> hvcat(3, A...)
4×3 Array{Int64,2}:
1 2 3
4 5 6
7 8 9
10 11 12
julia> vec(A)
12-element Array{Int64,1}:
1
2
3
4
5
6
7
8
9
10
11
12
So:
the first argument tells you how how many columns you want to produce
hvcat has h before v so it takes elements row-wise
however arrays store columns col-wise
so in effect you have to create the temporary array as a transpose of your target (because hvcat will take its columns to create rows of a target arrays). Actually this is only a coincidence - hvcat does not know that your original elements were storing in a matrix (it takes them as positional arguments to the call and at that time the fact that they were stored in a matrix is lost due to ... operation).
I have a vector and a matrix (Array{T,1} and Array{T,2}) in my Julia code and I would like to append them such that the vector becomes a new row in the matrix (should be first row). I've tried several methods (cat, etc.) but keep getting errors which I believe are related to the different shape of the data. See the example below.
julia> v = Vector([1, 2, 3])
3-element Array{Int64,1}:
1
2
3
julia> m = Matrix([4 5 6; 7 8 9])
2×3 Array{Int64,2}:
4 5 6
7 8 9
julia> cat(v,m,dims=(1,2))
5×4 Array{Int64,2}:
1 0 0 0
2 0 0 0
3 0 0 0
0 4 5 6
0 7 8 9
What I actually want is
1 2 3
4 5 6
7 8 9
I realize that I can get this to work with transpose(v) but I was hoping to avoid extra calls.
Thanks!
As long as you can change the construction of v to a 1 x 3 array, you can avoid the transpose:
julia> v = [1 2 3]
1×3 Array{Int64,2}:
1 2 3
julia> m = [4 5 6; 7 8 9]
2×3 Array{Int64,2}:
4 5 6
7 8 9
julia> vcat(v, m)
3×3 Array{Int64,2}:
1 2 3
4 5 6
7 8 9
I think that just doing the transpose
julia> v2 = [1, 2, 3]
3-element Array{Int64,1}:
1
2
3
julia> vcat(v2', m)
3×3 Array{Int64,2}:
1 2 3
4 5 6
7 8 9
is almost as efficient though.
How to conditionally increment if the previous value is greater than the current value? Say I have a column x on my data frame and I want a column y which starts from 1 and increments if the previous value is greater than the current.
x y
1 1
2 1
3 1
4 1
5 1
6 1
1 2
2 2
3 2
4 2
5 2
6 2
7 2
8 2
1 3
2 3
5 3
As #A5C1D2H2I1M1N2O1R2T1 mentioned, you can use cumsum with diff to generate y.
cumsum(diff(x) < 0) + 1
#[1] 1 1 1 1 1 2 2 2 2 2 2 2 2 3 3 3
You might want to prepend 1 in the beginning to get y with same length as x.
c(1, cumsum(diff(x) < 0) + 1)
#[1] 1 1 1 1 1 1 2 2 2 2 2 2 2 2 3 3 3
data
x <- c(1:6, 1:8, 1, 2, 5)
I have an input file of this form:
0.35217720 1 201 1
0.26413283 1 209 1
1.1665874 1 210 1
...
0.30815500 2 194 1
0.15407741 2 196 1
0.15407741 2 197 1
0.33016610 2 205 1
...
where the first column is a scalar value, the second is the x coordinate of a discrete lattice, the third is the y coordinate and the last one is time-like discrete component.
I would like to make a two dimensional heatmap of the scalar values at fixed time. How can i do? Edit: I don't know how to use image() to use the second and the third column as x, y coordinates.
Example file:
7.62939453 1 1 1
1.3153768 1 2 1
7.5560522 1 3 1
4.5865011 1 4 1
5.3276706 1 5 1
2.1895909 2 1 1
0.47044516 2 2 1
6.7886448 2 3 1
6.7929626 2 4 1
9.3469286 2 5 1
3.8350201 3 1 1
5.1941633 3 2 1
8.3096523 3 3 1
0.34571886 3 4 1
0.53461552 3 5 1
5.2970004 4 1 1
6.7114925 4 2 1
7.69805908 4 3 1
3.8341546 4 4 1
0.66842079 4 5 1
4.1748595 5 1 1
6.8677258 5 2 1
5.8897662 5 3 1
9.3043633 5 4 1
8.4616680 5 5 1
Reshape your data to a matrix and then use heatmap():
This worked on R version 2.10.1 (2009-12-14):
txt <- textConnection("7.62939453 1 1 1
1.3153768 1 2 1
7.5560522 1 3 1
4.5865011 1 4 1
5.3276706 1 5 1
2.1895909 2 1 1
0.47044516 2 2 1
6.7886448 2 3 1
6.7929626 2 4 1
9.3469286 2 5 1
3.8350201 3 1 1
5.1941633 3 2 1
8.3096523 3 3 1
0.34571886 3 4 1
0.53461552 3 5 1
5.2970004 4 1 1
6.7114925 4 2 1
7.69805908 4 3 1
3.8341546 4 4 1
0.66842079 4 5 1
4.1748595 5 1 1
6.8677258 5 2 1
5.8897662 5 3 1
9.3043633 5 4 1
8.4616680 5 5 1
")
df <- read.table(txt)
close(txt)
names(df) <- c("value", "x", "y", "t")
require(reshape)
dfc <- cast(df[ ,-4], x ~ y)
heatmap(as.matrix(dfc))
## Some copy/pasteable fake data for you (dput() works nicely for pasteable real data)
your_matrix <- cbind(runif(25, 0, 10), rep(1:5, each = 5), rep(1:5, 5), rep(1, 25))
heatmap_matrix <- matrix(your_matrix[, 1], nrow = 5)
## alternatively, if your_matrix isn't in order
## (The reshape method in EDi's answer is a nicer alternative)
for (i in 1:nrow(your_matrix)) {
heatmap_matrix[your_matrix[i, 2], you_matrix[i, 3]]
}
heatmap(heatmap_matrix) # one option
image(z = heatmap_matrix) # another option
require(gplots)
heatmap.2(heatmap_matrix) # this has fancier preferences