I am looking for a clever way to force the dimensions (both nrow and ncol) of a matrix to be even without using an if statement. By force I mean subtract the first appropriate column and/or row so that both dimensions are even.
I was hoping something like this would work:
## build a matrix with odd number of columns and even number of rows
x=matrix(1:12,nrow=4,ncol=3)
## we can check which (if any) dimensions are odd with
dim(x) %% 2 ## 0,1
## I would like get a matrix that looks like
[,1] [,2]
[1,] 5 9
[2,] 6 10
[3,] 7 11
[4,] 8 12
## By using something similar to
x.even = x[-nrow(x)%%2,-ncol(x)%%2]
Obviously the last line does not give the desired result. Is there a clever way to do this without using a conditional?
Just divide nrow and ncol by 2, take floor, and multiply by 2 again
x.even = x[1:(2*floor(nrow(x)/2)),1:(2*floor(ncol(x)/2))]
One way that builds on your solution:
#start rows and columns from 1
#also subtract remainder from total rows and columns
x[1:(nrow(x) - nrow(x) %% 2), 1:(ncol(x) - ncol(x) %% 2)]
output:
[,1] [,2]
[1,] 1 5
[2,] 2 6
[3,] 3 7
[4,] 4 8
Related
How to generate a matrix based on a comparison of two matrices. I have (column,row) matrix A (10,1) and B (10, 100). Matrix A is compared to each row of matrix B if the value of B is smaller than A then value B is updated to a value of A.
n.units<-100
n.option<-10
A<-rnorm(n.option,1,0.2)
B<-matrix(rnorm(n.option*n.units,1,0.2)n.col=n.units)
renew <-function(){Thresholds=obj.value }
update1 <- apply((Thresholds < obj.value),1,renew)
I am new to R programming, please give some advice to solve it.
I guess what you are trying can be achieved with pmax. Try
pmax(B, A)
You have a numeric vector A which is compared with matrix B. 1st element of A is compared with first row of B and the maximum value is selected. Same goes for all other rows since pmax recycles the shorter vector to the longer vector length. Also note that pmax(B, A) gives different structure than pmax(A, B) although the value is the same.
Just to make it easier to understand, consider this example
mat <- matrix(1:10, ncol = 5)
mat
# [,1] [,2] [,3] [,4] [,5]
#[1,] 1 3 5 7 9
#[2,] 2 4 6 8 10
pmax(mat, c(3, 7))
# [,1] [,2] [,3] [,4] [,5]
#[1,] 3 3 5 7 9
#[2,] 7 7 7 8 10
Here 1st row is compared with 3 and second row is compared with 7 and maximum value is selected.
Suppose you have a matrix a
a <- matrix(1:9, 3, 3)
a
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
and a vector b indicating which element of each row you want to extract. That is, the vector b indicates the column of the element, for instance:
b <- c(1, 3, 1)
If we want to extract the indicated data points, we can simply index each desired element like this:
a[cbind(1:nrow(a),b)]
[1] 1 8 3
I would like to do it with a negative index vector. That is, R should return a matrix where exactly one element per row is omitted (in this case, a 3x2 matrix). If I try it in a naive approach, R throws an error:
c = -b
a[cbind(1:nrow(a),c)]
Error in a[cbind(1:nrow(a), c)] :
negative values are not allowed in a matrix subscript
Thank you!
Not pretty, but you could do
b <- c(1, 3, 1) + 3 * 0:2
matrix(c(t(a))[-b], 3, 2, byrow = TRUE)
Maybe this is another naive approach. We loop over every row in the matrix and remove index specified in b.
t(sapply(seq_len(nrow(a)), function(x) a[x, -b[x]]))
# [,1] [,2]
#[1,] 4 7
#[2,] 2 5
#[3,] 6 9
Or using mapply with split
t(mapply(`[`, split(a, seq_len(nrow(a))), -b))
I have a simple matrix:
mat = rbind(c(1:3),c(4:6),c(7:9))
mat
# [,1] [,2] [,3]
# [1,] 1 2 3
# [2,] 4 5 6
# [3,] 7 8 9
I want to now reverse the matrix row-wise. That is I want to obtain:
revMat
# [,1] [,2] [,3]
# [1,] 3 2 1
# [2,] 6 5 4
# [3,] 9 8 7
To do this I tried
apply(mat, 1, rev)
And the result was:
# [,1] [,2] [,3]
# [1,] 3 6 9
# [2,] 2 5 8
# [3,] 1 4 7
I find this to be extremely strange. It's like the rows are reversed and then the final matrix is transposed. I don't understand why. If I try simply, for instance,
apply(mat, 2, rev)
it gives me the expected reversal of each column
# [,1] [,2] [,3]
# [1,] 7 8 9
# [2,] 4 5 6
# [3,] 1 2 3
Therefore to obtain the final result I have to perform
t(apply(t(bg), 2, rev))
Thus obtaining the required matrix is NOT a problem for me, but I don't understand the "anomaly" in the behavior of apply/ reverse. Can anyone explain this to me?
Edit: To make clear the distinction, I already know how to do the reversal. I want to know WHY this happens. How to is clear from many earlier questions including
How to reverse a matrix in R?
apply always puts the result in the first dimension. See ?apply for more information. Assuming this input:
mat <- matrix(1:9, 3, byrow = TRUE)
here are some alternatives:
1) transpose
t(apply(mat, 1, rev))
2) avoid apply with indexing
mat[, 3:1]
3) iapply An idempotent apply was posted here:
https://stat.ethz.ch/pipermail/r-help/2006-January/086064.html
Using that we have:
iapply(mat, 1, rev)
There was also an idempotent apply, iapply, in version 0.8.0 of the reshape package (but not in the latest version of reshape): https://cran.r-project.org/src/contrib/Archive/reshape/
4) rollapply rollapply in the zoo package can be used:
library(zoo)
rollapply(mat, 1, rev, by.column = FALSE)
5) tapply The tapply expression here returns a list giving us the opportunity to put it together in the way we want -- in this case using rbind:
do.call("rbind", tapply(mat, row(mat), rev))
6) multiply by a reverse diagonal matrix Since rev is a linear operator it can be represented by a matrix:
mat %*% apply(diag(3), 1, rev)
or
mat %*% (row(mat) + col(mat) == 3+1)
If you look at the help for apply(), this is exactly the behavior you would expect:
Value
If each call to FUN returns a vector of length n, then apply returns
an array of dimension c(n, dim(X)[MARGIN]) if n > 1.
a nice option to do what you want is to use indexing:
mat[,ncol(mat):1]
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 have some troubles in calculations in R. I have a vector of few numbers, and one sequence of numbers (vector as well, i think). Now i need to power all numbers of first vector on first element of second vector, sum that numbers and go on with each element of the second vector. So my result would be a vector of the same number of elements as the second vector. But i dont know how to program this equation. This is just the first part of my calculations, but i thing i can solve the rest by myself.
Thanks for reply!
Like this?
x <- 1:5
y <- 1:3
res <- outer(x, y, "^")
# [,1] [,2] [,3]
# [1,] 1 1 1
# [2,] 2 4 8
# [3,] 3 9 27
# [4,] 4 16 64
# [5,] 5 25 125
colSums(res)
#[1] 15 55 225