R which function displays wrong row numbers - r

I am trying to save the row number for values equal to one, for every column seperatly in a matrix (matx). The matrix should contain 0's for every other object. It somehow worked to give me numbers which are just a little bit smaller (1 value smaller in the beginning, two and three later on), but not the right values. The original matrix has just values of 0 and 1.
My try:
matx<-replicate(n=100,rbinom(n= 250, size=1, prob = 0.01))
maty<-apply(!matx, 2, function(x) ifelse(x==0,
which(x %in% 1),
x==0))
also tried:
maty<-apply(!matx, 2, function(x) ifelse(x>0, as.integer(rownames(matx)), 0))
The second attempt just leaves me with NA's and 0's instead of the row number.

Assuming that #akrun's interpretation is correct (it's also how I read the question) you can also use the row function:
matx * row(matx)
# [,1] [,2] [,3] [,4] [,5]
# [1,] 0 1 0 0 0
# [2,] 0 0 2 0 0
# [3,] 3 3 3 0 0
# [4,] 4 4 0 0 0
# [5,] 5 0 0 5 0
# [6,] 6 6 6 0 0
# [7,] 0 0 0 7 0
# [8,] 8 0 8 8 0
# [9,] 9 9 9 9 0
# [10,] 0 0 0 10 0

If we need to replace the '1s' (in the binary matrix) with the corresponding row numbers leaving the '0s' as such, we can can which with arr.ind=TRUE to get the row/column index of non-zero numbers, use that index to replace the 1s with the row index column from 'ind'. Here, I created a copy of 'matx' (ie. 'maty') in case the original matrix is needed.
maty <- matx
ind <- which(matx!=0, arr.ind=TRUE)
maty[ind] <- ind[,1]
maty
# [,1] [,2] [,3] [,4] [,5]
#[1,] 0 1 0 0 0
#[2,] 0 0 2 0 0
#[3,] 3 3 3 0 0
#[4,] 4 4 0 0 0
#[5,] 5 0 0 5 0
#[6,] 6 6 6 0 0
#[7,] 0 0 0 7 0
#[8,] 8 0 8 8 0
#[9,] 9 9 9 9 0
#[10,] 0 0 0 10 0
and original matrix
matx
# [,1] [,2] [,3] [,4] [,5]
#[1,] 0 1 0 0 0
#[2,] 0 0 1 0 0
#[3,] 1 1 1 0 0
#[4,] 1 1 0 0 0
#[5,] 1 0 0 1 0
#[6,] 1 1 1 0 0
#[7,] 0 0 0 1 0
#[8,] 1 0 1 1 0
#[9,] 1 1 1 1 0
#[10,] 0 0 0 1 0
NOTE: This could be also used for non-numeric elements
Or a base R modification of apply solution in #eipi's post would be
apply(matx, 2,function(x) ifelse(x!=0, seq_along(x), 0) )
data
set.seed(24)
matx <- matrix(sample(0:1, 10*5, replace=TRUE), nrow=10)

If your original matx is purely 0s and 1s then this show work:
maty <- matx * row(matx)
an example:
> matx # stealing from akrun
[,1] [,2] [,3] [,4] [,5]
[1,] 0 1 0 0 0
[2,] 0 0 1 0 0
[3,] 1 1 1 0 0
[4,] 1 1 0 0 0
[5,] 1 0 0 1 0
[6,] 1 1 1 0 0
[7,] 0 0 0 1 0
[8,] 1 0 1 1 0
[9,] 1 1 1 1 0
[10,] 0 0 0 1 0
> matx * row(matx)
[,1] [,2] [,3] [,4] [,5]
[1,] 0 1 0 0 0
[2,] 0 0 2 0 0
[3,] 3 3 3 0 0
[4,] 4 4 0 0 0
[5,] 5 0 0 5 0
[6,] 6 6 6 0 0
[7,] 0 0 0 7 0
[8,] 8 0 8 8 0
[9,] 9 9 9 9 0
[10,] 0 0 0 10 0

Here's a way to do it using apply:
library(zoo) # For index function
apply(matx, 2, function(x) ifelse(x==1, index(x), 0))

Related

replace a vector to an upper Triangle matrix with different length

I want to have a triangle matrix by a vector when length of vector is less than replacement length.
for example:
v<- c(1,2,3,4,5,6)
and
mat<- matrix(0,5,5).
If I use
mat[upper.tri(mat, diag=FALSE)]<- v
,the result is:
[,1] [,2] [,3] [,4] [,5]
[1,] 0 1 2 4 1
[2,] 0 0 3 5 2
[3,] 0 0 0 6 3
[4,] 0 0 0 0 4
[5,] 0 0 0 0 0
But i don't want to replace more than length of vector in matrix. And i want to have:
[1,] 0 1 2 4 0
[2,] 0 0 3 5 0
[3,] 0 0 0 6 0
[4,] 0 0 0 0 0
[5,] 0 0 0 0 0
You could adjust the length of v to that of the upper triangle. This yields some NA values that you can replace with zeroes.
u.tri <- upper.tri(mat, diag=FALSE)
mat[u.tri] <- `length<-`(v, length(u.tri))
mat[is.na(mat)] <- 0
# [,1] [,2] [,3] [,4] [,5]
# [1,] 0 1 2 4 0
# [2,] 0 0 3 5 0
# [3,] 0 0 0 6 0
# [4,] 0 0 0 0 0
# [5,] 0 0 0 0 0

How to loop through a dataset subtracting the value in the row below - Using R

I need help with the below question in R language.
Lets say I have a data set:
X Y
1 1
2 2
3 3
4 4
How would I go about looping through the dataset subtracting the X value in the current row from the X value in the row below, then going to the second row etc?
Currently I have the below:
df <- (df[row(df)-1,1] - df[row(df)+1,1])
I would like to get the following:
X
-1
-1
-1
N/a
However it seems to being doing the calculations twice and I am getting?
X
-1
-1
-1
N/a
-1
-1
-1
N/a
I cant figure out why, any help would be appreciated?
As #Sotos pointed out, you can solve this with diff.
But the reason this isn't working is because row() returns row numbers for both columns
> row(df)
[,1] [,2]
[1,] 1 1
[2,] 2 2
[3,] 3 3
[4,] 4 4
If you select either column alone your code works:
df <- (df[row(df)[,1]-1,1] - df[row(df)[,1]+1,1])
You could use diff(). Also you could do it using a matrix multiplication approach.
Example
set.seed(42)
x <- sample(10, 10, replace=TRUE)
> x
[1] 10 10 3 9 7 6 8 2 7 8
> diff(x)
[1] 0 -7 6 -2 -1 2 -6 5 1
# difference matrix approach
lbd <- matrix(0, nrow=length(x) - 1, ncol=length(x)) # setup lambda
diag(lbd) <- -1
diag(lbd[, -1]) <- 1
> lbd
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] -1 1 0 0 0 0 0 0 0 0
[2,] 0 -1 1 0 0 0 0 0 0 0
[3,] 0 0 -1 1 0 0 0 0 0 0
[4,] 0 0 0 -1 1 0 0 0 0 0
[5,] 0 0 0 0 -1 1 0 0 0 0
[6,] 0 0 0 0 0 -1 1 0 0 0
[7,] 0 0 0 0 0 0 -1 1 0 0
[8,] 0 0 0 0 0 0 0 -1 1 0
[9,] 0 0 0 0 0 0 0 0 -1 1
> lbd %*% x # matrix multiplication, same result as in `diff(x)` above
[,1]
[1,] 0
[2,] -7
[3,] 6
[4,] -2
[5,] -1
[6,] 2
[7,] -6
[8,] 5
[9,] 1
Using your data:
x1 <- 1:4
lbd1 <- matrix(0, nrow=length(x1) - 1, ncol=length(x1))
diag(lbd1) <- -1
diag(lbd1[, -1]) <- 1
> lbd1 %*% x1
[,1]
[1,] 1
[2,] 1
[3,] 1
> diff(x1) # same
[1] 1 1 1

row bind matrices, zero out all rows but one

Given a matrix
a <- matrix(c(15,2,11,16,7,12,1,8,3), nrow=3, ncol=3, byrow=T)
I'd like to row bind three copies of the matrix, but in each copy all rows but one should have zero values. The desired result:
15 2 11
0 0 0
0 0 0
0 0 0
16 7 12
0 0 0
0 0 0
0 0 0
1 8 3
I can do this by rbind(a[1,],0,0,0,a[2,],0,0,0,a[3,]), but is there a better way when dealing with a large matrix?
matrix(t(cbind(a,matrix(0,3,9))),ncol=3,byrow=T)[1:9,]
[,1] [,2] [,3]
[1,] 15 2 11
[2,] 0 0 0
[3,] 0 0 0
[4,] 0 0 0
[5,] 16 7 12
[6,] 0 0 0
[7,] 0 0 0
[8,] 0 0 0
[9,] 1 8 3
How about this:
apply(a, 2, function(r) rbind(r, matrix(rep(0,9), nrow=3)))[1:9, ]
[,1] [,2] [,3]
[1,] 15 2 11
[2,] 0 0 0
[3,] 0 0 0
[4,] 0 0 0
[5,] 16 7 12
[6,] 0 0 0
[7,] 0 0 0
[8,] 0 0 0
[9,] 1 8 3

Generate large matrix filled with 0's or 1's in R

In R language, I am trying to generate a large matrix filled with 0's and 1's.
I have generated a large matrix but its filled with values between 0 and 1.
Here is how I did that:
NCols=500
NRows=700
mr<-matrix(runif(NCols*NRows), ncol=NCols)
I think you are asking how to generate a matrix with just zero and 1
Here is how I would do it
onezero <- function(nrow,ncol)
matrix(sample(c(0,1), replace=T, size=nrow*ncol), nrow=nrow)
With nrow and ncol the rows and columns of the matrix
R> onezero(5,5)
[,1] [,2] [,3] [,4] [,5]
[1,] 1 1 0 1 0
[2,] 1 1 1 1 0
[3,] 1 1 0 0 0
[4,] 1 0 0 1 0
[5,] 0 0 0 0 0
You can use rbinomtoo. And can change the probability of success on each trial. In this case, it's .5.
nrow<-700
ncol<-500
mat01 <- matrix(rbinom(nrow*ncol,1,.5),nrow,ncol)
> number.of.columns = 5
> number.of.rows = 10
> matrix.size = number.of.columns*number.of.rows
> ones.and.zeros.samples = sample(0:1, matrix.size, replace=TRUE)
> A = matrix(ones.and.zeros.samples, number.of.rows)
> A
[,1] [,2] [,3] [,4] [,5]
[1,] 0 0 0 1 1
[2,] 1 0 0 0 1
[3,] 0 1 1 0 0
[4,] 0 0 1 1 1
[5,] 1 0 1 1 0
[6,] 0 1 0 1 1
[7,] 0 0 1 1 0
[8,] 0 1 0 0 0
[9,] 0 0 0 0 0
[10,] 0 0 0 1 1

How can I create a matrix as shown below in R

I am trying to create a matrix from a given vector in R, but I don't know how to achieve it in simple ways. I am giving an example below. The matrix was made using the "cbind" function.
Given x as
[1,] 1
[2,] 3
[3,] 4
how can I create the matrix below with simple method?
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 1 0 0 0 0 0
[2,] 3 1 0 0 0 0
[3,] 4 3 1 0 0 0
[4,] 0 4 3 1 0 0
[5,] 0 0 4 3 1 0
[6,] 0 0 0 4 3 1
[7,] 0 0 0 0 4 3
[8,] 0 0 0 0 0 4
Thank you for your help!
Using append and sapply
sapply(0:5, append, x = rep(0,5), values = c(1,3,4))
# [,1] [,2] [,3] [,4] [,5] [,6]
# [1,] 1 0 0 0 0 0
# [2,] 3 1 0 0 0 0
# [3,] 4 3 1 0 0 0
# [4,] 0 4 3 1 0 0
# [5,] 0 0 4 3 1 0
# [6,] 0 0 0 4 3 1
# [7,] 0 0 0 0 4 3
# [8,] 0 0 0 0 0 4
matrix(c(1,3,4,rep(0,6)),ncol=6,nrow=8)
You'll get a warning, but the correct matrix. If you don't like the warning just use suppressWarnings:
suppressWarnings(matrix(c(1,3,4,rep(0,6)),ncol=6,nrow=8))
Of course, be careful with that function if you are trying to abstract this to more general cases.
This method is very intuitive:
x <- c(1,3,4)
n <- 6
m <- matrix(0,ncol=n,nrow=n+length(x)-1)
diag(m) <- 1
diag(m[-1,]) <- 3
diag(m[-c(1, 2),]) <- 4
Assigning along diagonals can be automated easily, for example with a 'for' loop
for(i in seq_along(x)) diag(m[1:n + i - 1,]) <- x[i]
Both approaches yield:
R> m
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 1 0 0 0 0 0
[2,] 3 1 0 0 0 0
[3,] 4 3 1 0 0 0
[4,] 0 4 3 1 0 0
[5,] 0 0 4 3 1 0
[6,] 0 0 0 4 3 1
[7,] 0 0 0 0 4 3
[8,] 0 0 0 0 0 4
This works. (edit: no votes, maybe too telegraphic?) The idea is to create an all-zero matrix with the appropriate dimensions, and then use row/column arithmetic (using the row() and col() functions) to fill in the desired values in the elements where row-column is between 0 and 2 (i.e. the diagonal and the first two lower off-diagonals). This does rely on the column-major structure of matrices in R ...
x <- c(1,3,4)
n <- 6
m <- matrix(0,ncol=n,nrow=n+length(x)-1)
betw <- function(x,a,b) x>=a & x<= b
m[betw(row(m)-col(m),0,2)] <- x

Resources