Putting specific values of vector the rows of matrix - r

I have a vector like this :
Sum<-c(24, 32, 40, 48, 56, 28, 36, 44, 52, 60)
now i want to make a matrix of this vector like the first 5 values of the vector should become the first row of the matrix and the rest five as second row like this.
1 2 3 4 5
1 24 32 40 48 56
2 28 36 44 52 60
when i use the matrix function it gives me output like this which i don't want:
[,1] [,2] [,3] [,4] [,5]
[1,] 24 40 56 36 52
[2,] 32 48 28 44 60
Is there a way to get the desired output??
Thanks for any help.

Use the byrow parameter of matrix
m <- matrix(Sum, nrow=2, byrow=T)
See ?matrix for more help

Related

Vector to a matrix where the next row starts 1 observation

Suppose I have a data set with 40 observations
y <- rnorm(40,10,10)
Now I would like to transform this vector into a matrix with 4 observations in each row.
On top of that, I would like the row to start with value y[i] and add one each iteration upuntil the 40th observation.
So for example:
r1 = y[1] y[2] y[3] y[4]
r2 = y[2] y[3] y[4] y[5]
r3 = y[3] y[4] y[5] y[6]
.
.
r40 = y[39] y[38] y[37] y[36]
Does anyone know how to do this?
You can use matrix like:
y <- 1:40
matrix(y, 41, 4)[1:37,]
# [,1] [,2] [,3] [,4]
# [1,] 1 2 3 4
# [2,] 2 3 4 5
# [3,] 3 4 5 6
#...
#[35,] 35 36 37 38
#[36,] 36 37 38 39
#[37,] 37 38 39 40
Or using seq in mapply and fill the index matrix with the values of y.
i <- 1:37
M <- t(mapply(seq, i, i+3))
M
# [,1] [,2] [,3] [,4]
# [1,] 1 2 3 4
# [2,] 2 3 4 5
# [3,] 3 4 5 6
#...
#[35,] 35 36 37 38
#[36,] 36 37 38 39
#[37,] 37 38 39 40
M[] <- y[M]
This is one way to produce the first 37 rows. If you want to change the direction for the last 3 rows, then it would be easy to do with the same code:
purrr::map(seq_len(37), ~y[.x:(.x+3)]) %>%
unlist() %>%
matrix(nrow = 37, byrow = T)
Only difference would be to first save the values of the first 37 rows, then produce the last 3 rows, bind them, and turn that vector to a matrix.
Try embed
embed(y, 4)[, 4:1]
which could give the desired output

assign() for only one sheet of an array - avoid manual change

I have some arrays that I will need to fill in. The names of the arrays are variable, but the same functions will happen to them throughout. Basically I need a way to replace only one "sheet" of an array with another without manually entering the array name. Example below:
big_array_1 <- array(dim = c(5,5,10))
big_array_1[,,1] <- sample(c(1:10), 25, replace=T)
big_array_2 <- array(dim = c(5,5,10))
big_array_2[,,1] <- sample(c(40:50), 25, replace=T)
small_array <- array(dim = c(5,5,2))
small_array[,,] <- sample(c(20:30), 50, replace=T)
so each big array will have to have its second sheet (the third dimension) replaced by the second sheet of the small array, but I want to just be able to set a number (i.e. big array "1" or "2") to make this work in my code instead of change the name manually every time.
# So I know I can do this, but I want to avoid manually changing the "_1" to "_2" when I run the script
big_array_1[,,2] <- small_array[,,2]
# instead, I'm hoping I can use a variable and some kind of assign()
arraynumber <- 1
# but this gives an error for assigning a non-language object
get(paste0("big_array_",arraynumber))[,,2] <- small_array[,,2]
# and this gives an error for invalid first argument.
assign(get(paste0("big_array_",arraynumber))[,,2], small_array[,,2])
# even though get(paste0("big_array_",arraynumber))[,,2] works on its own.
Any suggestions?
In R, you cannot assign values to the result of get(). Additionally, it is not advisable to use assign even attach, eval+parse, list2env, and other environment-changing, dynamic methods that tend to be hard to debug.
As commented, simply use named lists for identically structured objects. Lists can contain any object from arrays to data frames to plots without a number limit. Even more, you avoid flooding global environment with separately named objects but work with a handful of lists containing many underlying elements which better manages data for assignment or iterative needs.
Definition
set.seed(8620)
# NAMED LIST OF TWO ARRAYS
big_array_list <- list(big_array_1 = array(dim = c(5,5,10)),
big_array_2 = array(dim = c(5,5,10)))
big_array_list$big_array_1[,,1] <- sample(c(1:10), 25, replace=TRUE)
big_array_list$big_array_2[,,1] <- sample(c(40:50), 25, replace=TRUE)
# NAMED LIST OF ONE ARRAY
small_array_list <- list(small_array_1 = array(sample(c(20:30), 50, replace=TRUE),
dim = c(5,5,2)))
Assignment
# ASSIGN BY FIXED NAME
big_array_list$big_array_1[,,2] <- small_array_list$small_array_1[,,2]
big_array_list$big_array_1[,,2]
# [,1] [,2] [,3] [,4] [,5]
# [1,] 30 29 26 24 23
# [2,] 21 20 22 20 24
# [3,] 27 24 26 30 30
# [4,] 30 26 24 29 25
# [5,] 26 21 26 20 30
# ASSIGN BY DYNAMIC NAME
arraynumber <- 1
big_array_list[[paste0("big_array_",arraynumber)]][,,2] <- small_array_list[[paste0("small_array_",arraynumber)]][,,2]
big_array_list[[paste0("big_array_",arraynumber)]][,,2]
# [,1] [,2] [,3] [,4] [,5]
# [1,] 30 29 26 24 23
# [2,] 21 20 22 20 24
# [3,] 27 24 26 30 30
# [4,] 30 26 24 29 25
# [5,] 26 21 26 20 30
# ASSIGN BY INDEX
big_array_list[[1]][,,2] <- small_array_list[[1]][,,2]
big_array_list[[1]][,,2]
# [,1] [,2] [,3] [,4] [,5]
# [1,] 30 29 26 24 23
# [2,] 21 20 22 20 24
# [3,] 27 24 26 30 30
# [4,] 30 26 24 29 25
# [5,] 26 21 26 20 30
Iterative Needs
# RETURN DIMENSIONS OF EACH big_array
lapply(big_array_list, dim)
# SHOW FIRST 5 ELEMENTS OF EACH big_array
sapply(big_array_list, `[`, 1:5)
# RETURN LIST WHERE ALL big_arrays ARE EQUAL TO small_array
mapply(`<-`, big_array_list, small_array_list, SIMPLIFY=FALSE)

Unlist str_locate_all into separate start and end lists

I use str_locate_all to get the start and end positions of a list of patterns in my string. It returns a list with the start and stop position for each match. How can I get the start and stop positions of all matches into separate lists?
library(stringr)
patterns <- c("ABS", "BSDF", "ERIDF", "RTZOP")
string <- "ABSBSDFERIDFRTZOPABSBSDFRTZOPABSBSDFERIDFRTZOP"
matches <- str_locate_all(string, patterns)
Result:
[[1]]
start end
[1,] 1 3
[2,] 18 20
[3,] 30 32
[[2]]
start end
[1,] 4 7
[2,] 21 24
[3,] 33 36
[[3]]
start end
[1,] 8 12
[2,] 37 41
[[4]]
start end
[1,] 13 17
[2,] 25 29
[3,] 42 46
What I would like:
start <- c(1, 18, 30, 4, 21, 33, 8, 37, 13, 25, 42)
end <- c(3, 20, 32, 7, 24, 36, 12, 41, 17, 29, 46)
Use do.call with rbind to stack the lists together, then take out the desired columns.
> library(stringr)
>
> patterns <- c("ABS", "BSDF", "ERIDF", "RTZOP")
> string <- "ABSBSDFERIDFRTZOPABSBSDFRTZOPABSBSDFERIDFRTZOP"
>
> matches <- str_locate_all(string, patterns)
>
> all <- do.call(rbind, matches)
> start <- all[, 1]
> stop <- all[, 2]
> start
[1] 1 18 30 4 21 33 8 37 13 25 42
> stop
[1] 3 20 32 7 24 36 12 41 17 29 46

Indexing elements in matrix and corresponding column numbers

I have a matrix full of integers and I need to create an index where for each of these integers I get the numbers of columns containing it (using R).
For instance, suppose I have this table:
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 31738 3136023010 777150982 2318301701 44 3707934113
[2,] 1687741813 44 31738 1284682632 462137835 445275140
[3,] 44 123 123 31738 1215490197 123
In my case I have 31738 being present in columns:
1,2 and 4
elements: [1,1], [2,3] and [3,4]
and 44 being present in columns 1,2 and 5 (elements [3,1], [2,2] and [1,5]
So for all elements in my table, I need to have an index like
31738 = 1 3 4
3136023010 = 2
777150982 = 3
44 = 1 2 3
....
123 = 2 3 6
etc
edit: i corrected my mistake pointed out in comment bellow.
We can do
setNames(lapply(unique(m1), function(i)
as.vector(which(m1==i, arr.ind = TRUE)[,2])), unique(m1))
Or another option is
split(col(m1), m1)
data
m1 <- structure(c(31738, 1687741813, 44, 3136023010, 44, 123, 777150982,
31738, 123, 2318301701, 1284682632, 31738, 44, 462137835, 1215490197,
3707934113, 445275140, 123), .Dim = c(3L, 6L))

How to create a Matrix from an Array in R?

I have a simple array, like:
x <- c(10,20,30,40,50,60,70,80,90,100)
I would like to create a matrix from this array, because those numbers are prices of two stocks.
stock A: 10 30 50 70 90
stock B: 20 40 60 80 100
How can I create two columns from this list of prices.
Thank you
I suspect the OP actually wants:
> matrix(x, ncol = 2, byrow = TRUE)
[,1] [,2]
[1,] 10 20
[2,] 30 40
[3,] 50 60
[4,] 70 80
[5,] 90 100
or possibly
> split(x, rep(c("A","B"), length(x)/2))
$A
[1] 10 30 50 70 90
$B
[1] 20 40 60 80 100
which can be converted to a data frame easily enough...
Just push the vector into matrix
matrix(x, ncol = 2)
No need to specify the number of rows since that is implicit. See ?matrix

Resources