Moving Data from Matrix A to Matrix B in R - r

I want to cut/move/replace some data (to be precise 2500) from Matrix A to Matrix B in R.
for example Move cell(i,j) from matrix A to cell(i,j) in matrix B. both i and j have some fixed value(50 to be precise) and replace that cell(i,j) in matrix A with "0".
Since I am newto programming can anyone help me with the coding?
Thanks in Advance
Regards

You can first define a two column coordinate-matrix of the values you want to replace, where the first column refers is the row-index and the second column is the column-index. As an example, suppose you want to replace the cells c(2,1), c(2,2) and c(1,2) in a 3x3 matrix B with the calues from a 3x3 matrix A:
ind <- cbind(c(2,2,1), c(1,2,2))
A <- matrix(1:9, ncol = 3)
B <- matrix(NA, ncol = 3, nrow = 3)
B[ind] <- A[ind]; A[ind] <- 0
B
[,1] [,2] [,3]
[1,] NA 4 NA
[2,] 2 5 NA
[3,] NA NA NA
A
[,1] [,2] [,3]
[1,] 1 0 7
[2,] 0 0 8
[3,] 3 6 9

Related

How to remove parts of a column from matrix in R

Let's say I have a matrix
[,1] [,2] [,3] [,4]
[1,] 10 11 12 13
[2,] 9 10 15 4
[3,] 5 7 4 10
[4,] 1 2 6 2
I want to remove parts of a column where the values are <=5. Even if there is a higher value in the next row of the column (ie. [3,4] after [2,4] is <5), those will become 0, so I should be left with:
[,1] [,2] [,3] [,4]
[1,] 10 11 12 13
[2,] 9 10 15 NA
[3,] NA 7 NA NA
[4,] NA NA NA NA
The matrix was created by using a for-loop to iterate a population 100 times so my matrix is 100x100.
I tried to use an if function in the for-loop to remove parts of the column but instead it just removed all columns after the first one.
if(matrix[,col]<=5) break
Here's a way to replace the required values in a matrix with NA:
# Create a random matrix with 20 rows and 20 columns
m <- matrix(floor(runif(400, min = 0, max = 101)), nrow = 20)
# Function that iterates through a vector and replaces values <= 5
# and the following values with NA
f <- function(x) {
fillNA <- FALSE
for (i in 1:length(x)) {
if (fillNA || x[i] <= 5) {
x[i] <- NA
fillNA <- TRUE
}
}
x
}
# Apply the function column-wise
apply(m, 2, f)
We can do this in base R. Let's assume that your matrix is called m. The function below does the following:
Check each element to see if it is <= 5, producing TRUE/FALSE values.
Cumulatively sum the TRUE/FALSE values.
Replace any non-zero cumulative values with NA.
Use apply to perform this operation per column of the matrix.
This can be fit on one line:
m2 <- apply(m, 2, \(x) ifelse(cumsum(x <= 5), NA, x))
[,1] [,2] [,3] [,4]
[1,] 10 11 12 13
[2,] 9 10 15 NA
[3,] NA 7 NA NA
[4,] NA NA NA NA
# Load the necessary packages
library(dplyr)
# Set the seed for reproducibility
set.seed(123)
# Create a random matrix with 100 rows and 100 columns
matrix <- matrix(runif(10000), nrow = 100)
# Replace values in each row of the matrix that are <= 5 with NA
matrix[apply(matrix, 1, function(x) any(x <= 5)), ] <- NA
# View the modified matrix
matrix
This code first loads the dplyr package, which is not necessary for this task but is used here to create a random matrix. It then sets the seed for reproducibility, so that the same random matrix is generated every time the code is run. Next, it creates a random matrix with 100 rows and 100 columns using the runif function, which generates random uniform numbers between 0 and 1. Finally, it uses the apply function to apply the logic to each row of the matrix and replace any values that are <= 5 with NA.

Removing matrix elements under a certain value

I hava a matrix with dimensions below, the matrix contains calculated distances between a set of genetic variants, I would like to create a new matrix or modify the PosDiff matrix to only distances that are less than or equal to 500,000.
dim(PosDiff)
[1] 597 41099
i have tried subset(), setdiff() and get wonky results such as a matrix with 1 column and a 41099 observations
Thanks
Ok let's have a go
# Generate a random matrix with 4 rows and 3 cols
> m <- matrix(runif(12), nrow=4)
> m
# [,1] [,2] [,3]
#[1,] 0.62361346 0.7793682 0.9447203
#[2,] 0.14844661 0.7335280 0.2936238
#[3,] 0.08026447 0.8172304 0.1490721
#[4,] 0.46406955 0.1701625 0.7193786
# Then keep all the elements <= 0.5 setting all the rest to NA
> m1 <- apply(m, FUN=function(x){ifelse(x<=0.5, NA, x)}, MARGIN = c(1,2))
> m1
# [,1] [,2] [,3]
#[1,] NA NA NA
#[2,] 0.14844661 NA 0.2936238
#[3,] 0.08026447 NA 0.1490721
#[4,] 0.46406955 0.1701625 NA
If you just want only the values less than 0.5 then you can run m[which(m<=0.5)]
Maybe you just need:
ifelse(PosDiff <= 500000., PosDiff, NA)
or:
ifelse(PosDiff <= 500000., PosDiff, 0)
dependently on whether you want to have missing value or 0 instead of elements which are greater than 500000.

Matrix without the matrix function

I m trying to create a matrix in R without using matrix function I tried
this but it works just for 2 rows how do I specify nrows I have no idea
matrix2<-function(n)
{
d<-n/2
v1<-c(1:d)
v2<-c(d +1:n)
x<- rbind(v1,v2)
return(x)
}
I want to create a matrix without using the matrix function and byrow not bycolmun
exemple
a function I enter number of columns and the dimension N in my exemple and in return it creates a matrix
[,1] [,2]
[1,] 1 2
[2,] 3 4
[3,] 5 6
[4,] 7 8
for exepmle
This will give you a matrix for a specified number of columns. I wasn't sure what you meant with dimension N.
matrix2 <- function(N, columns){
d<-ceiling(N/columns) # rounds up to first integer
x <- c()
i <- 1
for(row in 1:d){
x <- rbind(x, c(i:(i+columns-1)))
i <- i+columns
}
return(x)
}
> matrix2(8,2)
[,1] [,2]
[1,] 1 2
[2,] 3 4
[3,] 5 6
[4,] 7 8
You can also use an indirection via a list. Then you can also set both, the column and the row number. And how the matrix is filled, row wise or column wise.
matrix2<-function(n,m,V,byRow=T){
if(length(V) != n*m ) warning("length of the vector and rows*columns differs" )
# split the vector
if(byRow) r <- n
if(!byRow) r <- m
fl <- 1:r # how often you have to split
fg <- sort(rep_len(fl,length(V))) # create a "splitting-vector"
L <- split(V,fg)
# convert the list to a matrix
if(byRow) res <- do.call(rbind,L)
if(!byRow) res <- do.call(cbind,L)
rownames(res) <- colnames(res) <- NULL
res #output
}
matrix2(2,4,1:8,F)
[,1] [,2] [,3] [,4]
[1,] 1 3 5 7
[2,] 2 4 6 8
matrix2(2,4,1:8,T)
[,1] [,2] [,3] [,4]
[1,] 1 2 3 4
[2,] 5 6 7 8

Adding elements to the diagonal of a matrix that is not square in R

I want to be able to add a value (in my code nug) to the i,j entry of a matrix where i = j (so like a Kronecker delta function). Its very easy to do when the matrix is square (see my code below) however I am not sure how to do it in one line when the matrix is not square
nug = 2
R = tau + diag(nug,nrow(tau))
The above code works when tau is a square matrix but now imagine that tau is not square. How would I add nug to each of the i,j elements of tau where i = j?
m <- matrix(1:6, ncol = 2)
m
[,1] [,2]
[1,] 1 4
[2,] 2 5
[3,] 3 6
diag(m) <- diag(m) + 1:2
m
[,1] [,2]
[1,] 2 4
[2,] 2 7
[3,] 3 6
You can do this :
m[col(m)==row(m)] <- m[col(m)==row(m)] +nug
Using a matrix of zeros to show this:
m <- matrix(rep(0,6), ncol = 2)
> m[col(m)==row(m)] <- m[col(m)==row(m)] +2
> m
[,1] [,2]
[1,] 2 0
[2,] 0 2
[3,] 0 0

repeat a matrix many times and get a vector of matrix names

I have a basic matrix mat and I hope to get an R object x = (mat, mat, ...) where mat is repeated for 100 times. If this is possible, then I can pass x to a function which takes a vector of matrix names. I tried rep(mat, 100) but it seems that the matrix class is no longer maintained. Any suggestions? Thanks!
Update: Basically I plan to use
grp.ids <- as.factor(c(rep(1,8), rep(2,4), rep(3,2)))
x <- model.matrix(~grp.ids)
do.call(blockMatrixDiagonal,
replicate(100, x, simplify=FALSE))
where the blockMatrixDiagonal function can be found here. Then R gives an error: number of items to replace is not a multiple of replacement length. What I really hope to get via these coding is a block diagonal matrix. Thanks :)
Your input matrix is not appropriate for building a block diagonal matrix since it's not a square matrix (i.e., the number of rows equals the number of columns).
Let me cite two resources on block diagonal matrices.
1) Wikipedia:
A block diagonal matrix is a block matrix which is a square matrix, and having main diagonal blocks square matrices
2) The description of the function blockMatrixDiagonal:
builds a block matrix whose diagonals are the square matrices provided.
You can combine your non-square matrices with the function adiag from the package magic. With your matrix x:
library(magic)
do.call(adiag, replicate(100, x, simplify = FALSE))
For a base R solution, check out kronecker
?kronecker
# For your block diagonal matrix:
kronecker(diag(1, 100), x)
# or with `%x%` alias
diag(1, 100) %x% x
# example 1
m <- matrix(1:6, nrow = 3)
kronecker(diag(1, 2), m)
# [,1] [,2] [,3] [,4]
# [1,] 1 4 0 0
# [2,] 2 5 0 0
# [3,] 3 6 0 0
# [4,] 0 0 1 4
# [5,] 0 0 2 5
# [6,] 0 0 3 6
# example 2
matrix(1, nrow = 2, ncol = 3) %x% m
# [,1] [,2] [,3] [,4] [,5] [,6]
# [1,] 1 4 1 4 1 4
# [2,] 2 5 2 5 2 5
# [3,] 3 6 3 6 3 6
# [4,] 1 4 1 4 1 4
# [5,] 2 5 2 5 2 5
# [6,] 3 6 3 6 3 6

Resources