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.
Related
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.
I have two a matrix where some of the cells within the matrices are NA and others are filled with a list of numbers. And what I need is a way to calculate the number of items within each list for each cell of the matrix.
Here is the matrix:
> matrix_1
[,1] [,2]
[1,] NA c(1001, 1002)
[2,] c(1001, 1003) NA
Here is what I am looking for:
[,1] [,2]
[1,] NA 2
[2,] 2 NA
The actual data set is much, much larger - so I am trying to avoid loops.
Here is the dput:
Matrix 1 = structure(list(NA, c(1001, 1003), c(1001, 1002), NA), .Dim = c(2L,
2L))
You could decide to do:
NA^is.na(matrix1) * lengths(matrix1)
[,1] [,2]
[1,] NA 2
[2,] 2 NA
or even:
`is.na<-`(lengths(matrix1), is.na(matrix1))
[,1] [,2]
[1,] NA 2
[2,] 2 NA
Maybe you can try lengths + replace like below
> replace(lengths(matrix_1),which(is.na(matrix_1)),NA)
[,1] [,2]
[1,] NA 2
[2,] 2 NA
It seems that your description of the question and the expected output are slightly different.
The number of items in a list element conaining a single NA is 1, not NA. So the answer to this is:
matrix1=matrix(list(NA,c(1001,1003),c(1001,1002),NA),nrow=2)
answer=array(lengths(matrix1),dim=dim(matrix1))
answer
# [,1] [,2]
# [1,] 1 2
# [2,] 2 1
However, if you want to convert all the elements corresponding a single NA entry to be NA themselves (in agreement with your expected output), you can do the extra step:
answer[is.na(matrix1)]=NA
answer
# [,1] [,2]
# [1,] NA 2
# [2,] 2 NA
Note that elements of more-than-one item, of which some are NA won't be detected by this last step... (you'd need to use answer[sapply(matrix1,function(x) any(is.na(x)))]=NA instead).
My aim is to delete specific positions in a matrix according to a vector. Just giving you a small example.
Users_pos <- c(1,2)
Items_pos <- c(3,2)
Given a Matrix A:
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 4 5 6
[3,] 7 8 9
My aim according to the two Vectors User_pos and Item_pos is to delete the following values
A[1,3] and A[3,2]
I'm wondering if there's a possibility to do so without typing in the values for rows and columns by hand.
You can index k elements in a matrix A using A[X], where X is a k-row, 2-column matrix where each row is the (row, col) value of the indicated element. Therefore, you can index your two elements in A with the following indexing matrix:
rbind(Users_pos, Items_pos)
# [,1] [,2]
# Users_pos 1 2
# Items_pos 3 2
Using this indexing, you could choose to extract the information current stored with A[X] or replace those elements with A[X] <- new.values. If you, for instance, wanted to replace these elements with NA, you could do:
A[rbind(Users_pos, Items_pos)] <- NA
A
# [,1] [,2] [,3]
# [1,] 1 NA 3
# [2,] 4 5 6
# [3,] 7 NA 9
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
I am trying to solve a little problem with a matrix in R. I have the next matrix in R (alfa):
alfa <- matrix(1:9,nrow=3)
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
The opposite diagonal of alfa is filled of zeros. I would like to get in a new matrix all elements over this opposite diagonal (maybe the upper triangle over this diagonal). I wish to get a new matrix like this:
[,1] [,2] [,3]
[1,] 1 4 0
[2,] 2 0 0
[3,] 0 0 0
Or like this matrix with NA:
[,1] [,2] [,3]
[1,] 1 4 0
[2,] 2 0 NA
[3,] 0 NA NA
Where the elements located down the opposite diagonal of alfa are zero or NA, as you can see. I have tried with code using row(alfa) and col(alfa) but I can't get the expected matrix, for example:
(row(alfa)+col(alfa)-1)%%ncol(alfa)!=0
And I got this result where both upper and down elements over opposite diagonal are TRUE:
[,1] [,2] [,3]
[1,] TRUE TRUE FALSE
[2,] TRUE FALSE TRUE
[3,] FALSE TRUE TRUE
But I only want the upper elements, and the rest elements should be filled with zero or NA.
Many thanks for your help.
lower.tri almost does what you want, but you need to reverse the rows.
alfa[apply(lower.tri(alfa), 1, rev)] <- NA
Here, the matrix of the lower anti-diagonal is built, and used to select into alfa (vector indexing) for replacement.
lower.tri has a diag argument, which will also select the diagonal if set to TRUE.
f <- function(mat, diag = 0, offdiag = NA){
rev_vec <- seq(ncol(mat), 1)
j <- mat[,rev_vec]
j[lower.tri(j)] <- offdiag
diag(j) <- diag
j[,rev_vec]
}
You can specify if you want the off-diagonals to be NA or 0 by changing the offdiag parameter.