Applying a function to sub-matrices within a larger matrix - r

So I have a 1256 by 5 matrix.
> head(retmatx12.30.3)
AMT HON KO
[1,] -0.006673489 -0.001292867 -0.0033654493
[2,] 0.004447249 0.002848406 0.0082009877
[3,] 0.001789891 0.002754232 -0.0035886573
[4,] -0.003479321 0.002231823 0.0024011113
[5,] -0.006605786 0.015159190 -0.0002394852
[6,] -0.002375004 -0.008267790 -0.0100625938
NEM NVAX
[1,] -0.034023392 -0.023255737
[2,] 0.016436786 0.007936468
[3,] 0.009529404 0.031496102
[4,] 0.046052588 0.007633549
[5,] -0.031446425 0.037878788
[6,] -0.001694084 0.036496350
I want to apply a function I've made to rows 1-126, then 2-127, and so on. The function is a block of matrix algebra that uses a matrix and a few vectors. Is it wise to somehow break the larger matrix into 1,131 126 by 5 matrices, and apply the function over each (hopefully at once). Or, some sort of application of apply?
Any help is greatly appreciated. Thanks

The actual numbers in the matrix are immaterial, so I'll use much smaller data to demonstrate one method, and a simple function to demonstrate the rolling calculation:
m <- matrix(1:24, nrow=8)
somefunc <- function(x) x %*% seq(ncol(x))
wid <- 4 # 126
somefunc(m[1:4,])
# [,1]
# [1,] 70
# [2,] 76
# [3,] 82
# [4,] 88
somefunc(m[2:5,])
# [,1]
# [1,] 76
# [2,] 82
# [3,] 88
# [4,] 94
The actual rolling work:
lapply(seq(nrow(m) - wid + 1), function(i) somefunc(m[i - 1 + seq(wid),]))
# [[1]]
# [,1]
# [1,] 70
# [2,] 76
# [3,] 82
# [4,] 88
# [[2]]
# [,1]
# [1,] 76
# [2,] 82
# [3,] 88
# [4,] 94
# [[3]]
# [,1]
# [1,] 82
# [2,] 88
# [3,] 94
# [4,] 100
# [[4]]
# [,1]
# [1,] 88
# [2,] 94
# [3,] 100
# [4,] 106
# [[5]]
# [,1]
# [1,] 94
# [2,] 100
# [3,] 106
# [4,] 112
where the first element of the output is from rows 1-4, then 2-5, then 2-6, etc.

Related

How to convert only row matrices in a list to column matrices in R?

I have a list of matrices where most of the matrices are column matrices but some of them are row matrices. How to convert only those row matrices to column matrices? I would like to achieve this using base R.
Here is the list of matrices where the third one is a row matrix
x <- list(`1` = matrix(1:20, nrow=5), `2` = matrix(1:20, nrow=10), `3` = matrix(1:5, nrow=1))
How to convert the list to one like this:
$`1`
[,1] [,2] [,3] [,4] [,5]
[1,] 1 3 5 7 9
[2,] 2 4 6 8 10
$`2`
[,1] [,2]
[1,] 1 6
[2,] 2 7
[3,] 3 8
[4,] 4 9
[5,] 5 10
$`3`
[1,] 1
[2,] 2
[3,] 3
[4,] 4
[5,] 5
I have a much larger dataset and so efficient code is preferred!
Check the dimensions of the matrix and transpose it if the row dimension is 1:
(y <- lapply(x, function(x) if(dim(x)[1] == 1) { t(x)} else x))
# $`1`
# [,1] [,2] [,3] [,4]
# [1,] 1 6 11 16
# [2,] 2 7 12 17
# [3,] 3 8 13 18
# [4,] 4 9 14 19
# [5,] 5 10 15 20
#
# $`2`
# [,1] [,2]
# [1,] 1 11
# [2,] 2 12
# [3,] 3 13
# [4,] 4 14
# [5,] 5 15
# [6,] 6 16
# [7,] 7 17
# [8,] 8 18
# [9,] 9 19
# [10,] 10 20
#
# $`3`
# [,1]
# [1,] 1
# [2,] 2
# [3,] 3
# [4,] 4
# [5,] 5

Make a loop in R from first value of a column to last value of a column

How can I make a loop in R that operates from the first row of a column to the end of that column? something like from x[1,2] to tail(x[,2], n=1)
You could use nrow.
(m <- matrix(1:18, 6, 3))
# [,1] [,2] [,3]
# [1,] 1 7 13
# [2,] 2 8 14
# [3,] 3 9 15
# [4,] 4 10 16
# [5,] 5 11 17
# [6,] 6 12 18
for (i in 1:nrow(m)) {
m[i, 2] <- m[i, 2] + 100
}
m
# [,1] [,2] [,3]
# [1,] 1 107 13
# [2,] 2 108 14
# [3,] 3 109 15
# [4,] 4 110 16
# [5,] 5 111 17
# [6,] 6 112 18
However, since R is vectorized you may take the whole column and do vector operations.
m[, 3] <- m[, 3] + 100
m
# [,1] [,2] [,3]
# [1,] 1 107 113
# [2,] 2 108 114
# [3,] 3 109 115
# [4,] 4 110 116
# [5,] 5 111 117
# [6,] 6 112 118

Avoiding pseudorandom number generation in R

How can I randomly sample n integers (let's say from 1 to 200) avoiding the pseudorandom problem? I'm currently using sample(), but the sequence generated is the same every time I run my code.
Having not seen your code, it sounds like you are (unintentionally) reseeding the RNG. At any rate, if you are interested in avoiding any possible issues that stem from PRNGs you can use the random package, which utilizes random.org's true random number generator. For example,
set.seed(123)
R> random::randomNumbers(10, 1, 200, col = 1)
# V1
# [1,] 178
# [2,] 171
# [3,] 20
# [4,] 47
# [5,] 113
# [6,] 75
# [7,] 120
# [8,] 125
# [9,] 98
# [10,] 15
set.seed(123)
R> random::randomNumbers(10, 1, 200, col = 1)
# V1
# [1,] 112
# [2,] 84
# [3,] 83
# [4,] 20
# [5,] 19
# [6,] 112
# [7,] 64
# [8,] 134
# [9,] 105
# [10,] 63

Delete row based on the value of the rows above

I have a the following data set:
data <- cbind(c(1,2,3,4,5,6,7,8,9,10,11),c(1,11,21,60,30,2,61,12,3,35,63))
I would like to select the rows for which the number in the second column is greater than the highest number reached up to that point. The result should look like this.
[,1] [,2]
[1,] 1 1
[2,] 2 11
[3,] 3 21
[4,] 4 60
[5,] 7 61
[6,] 11 63
You want to try cummax:
> d[ d[,2] == cummax(d[,2]) ,]
[,1] [,2]
[1,] 1 1
[2,] 2 11
[3,] 3 21
[4,] 4 60
[5,] 7 61
[6,] 11 63
PS. data is an internal R function, so, since R variables and functions share the namespace (R design was influenced by Scheme, which is a "Lisp-1"), your variable shadows the system function.
The cummax function should work well
data[ data[,2]==cummax(data[,2]),]
returns
[,1] [,2]
[1,] 1 1
[2,] 2 11
[3,] 3 21
[4,] 4 60
[5,] 7 61
[6,] 11 63
as desired.

how can random grouping a matrix in r?

I want to generate m^2 element from bi-variate normal, then divided them to m group with m size.
each row of this matrix is pair and i need to keep it.
for example I generated a matrix.
m <- 5
mu <- c(1,2)
Sigma <- matrix(c(5,2,2,10), nr=2)
A <- mvrnorm(n = m^2, mu, Sigma, tol = 1e-6, empirical = FALSE, EISPACK = FALSE)
A
[,1] [,2]
[1,] 2.9553065 5.98908423
[2,] -1.8670295 5.10591725
[3,] 0.4525815 -1.38689984
[4,] -0.2505460 0.55450966
[5,] -1.1744521 2.45349132
[6,] 0.2772808 2.51802656
[7,] 1.2252624 2.68861855
[8,] -0.3800679 -0.95790121
[9,] -1.8994312 -2.65912013
.
.
.
[22,] 0.1072236 0.07729866
[23,] 2.1108011 -0.64723640
[24,] 0.2431816 1.04820102
[25,] 0.7361761 1.96943700
How can I do this?
Please help me
Thanks
Nasrin
First, you need to determine which samples are going to end up in each of the m random samples:
random_indices = matrix(sample(m^2), m, m)
random_indices
[,1] [,2] [,3] [,4] [,5]
[1,] 14 1 16 21 23
[2,] 11 10 24 3 15
[3,] 17 2 13 20 19
[4,] 22 5 18 8 6
[5,] 9 25 7 4 12
Next, we need to extract the actual samples. Here, each sub-sample contains the samples from your A matrix mentioned in the rows of random_indices. The result is a list with for each of the m subsets, m samples:
lapply(seq_len(nrow(random_indices)), function(x) A[random_indices[x,],])
[[1]]
[,1] [,2]
[1,] 2.7177656 6.844050
[2,] 2.2583187 2.824858
[3,] -2.3599720 -6.089002
[4,] -0.8386464 3.994062
[5,] 3.4257535 1.107403
[[2]]
[,1] [,2]
[1,] -0.5054434 -1.2499055
[2,] -1.6383755 7.6674873
[3,] 3.1938874 -3.1286704
[4,] 0.6332935 3.4084193
[5,] -3.0407672 -0.6030366
[[3]]
[,1] [,2]
[1,] 0.2296299 5.0697808
[2,] 0.6292743 0.9794591
[3,] 1.1109314 7.3588483
[4,] 2.1835536 3.0048715
[5,] -0.2173142 1.4850735
[[4]]
[,1] [,2]
[1,] 3.36705377 1.487134
[2,] -0.05987684 4.881800
[3,] 0.61090216 3.632019
[4,] 0.39473322 1.067586
[5,] 5.77516329 8.382878
[[5]]
[,1] [,2]
[1,] -2.3590412 -2.133053
[2,] 0.2696948 3.986496
[3,] 0.2362004 -6.120856
[4,] 1.9769119 7.343788
[5,] 2.4542632 1.870695

Resources