R indexing issue - r

Sorry for vague question title, i couldn't figure out something more specific.
I have 3x2 matrix c:
> c
[,1] [,2]
[1,] 1 2
[2,] 1 3
[3,] 2 3
It is important that ncol(c) == 2.
I also have matrix ind:
> ind
[,1] [2] [,3] [,4]
[1,] 2 2 2 1
[2,] 1 1 2 2
[3,] 2 2 2 1
It is important that nrow(c) == nrow(ind), and that the values of matrix ind are 1 and 2 (like column indices for each row of c)
What i want to get is matrix a with same dim as ind such that a[i,j] == c[i,ind[i,j]]:
> a
[,1] [2] [,3] [,4]
[1,] 2 2 2 1
[2,] 1 1 3 3
[3,] 3 3 3 2
I can do something similar in less comprehensive situations, for example if nrow(c) == 1 i'll use apply:
> apply(c,2,function(x){return(matrix(x[ind], nrow(ind)))})
I know there is a way to iterate by 2 lists using mapply, but
1) i don't know what's the best way to represent matrix as list of rows
2) i fing this solution ugly
What is the best way to achieve what i descibed here?

Matrix indexing to the rescue!
> c.mat <- matrix(c(1,1,2,2,3,3), ncol=2)
> ind <- matrix(c(2,1,2,2,1,2,2,2,2,1,2,1), ncol=4)
> matrix(c.mat[cbind(as.vector(row(ind)), as.vector(ind))], ncol=ncol(ind))
[,1] [,2] [,3] [,4]
[1,] 2 2 2 1
[2,] 1 1 3 3
[3,] 3 3 3 2

f<-function(x,row1){
for(i in 1:length(x)){
x[i]=cc[i,ind[i,row1]]
}
x
}
a=apply(cc,1,f,nrow(a))
You can use apply like this. Note: cc is your c matrix

Related

Subsettings rows containing specific values

I am generating a matrix of all combinations of 5 numbers taken 3 at a time, without replacement, like this:
v <- seq(1,5,1)
combs <- t(combn(v,3))
Part of the output is as following:
[,1] [,2] [,3]
[,1] 1 2 3
[,2] 1 2 4
[,3] 1 2 5
[,4] 1 3 4
[,5] 1 3 5
.
.
.
Now, I want to filter out all rows containing, for example, numbers 1 and 3, where the remaining element doesn't matter.
How can this be done?
Thank you
Here is one way using rowSums :
combs[rowSums(combs == 1) > 0 & rowSums(combs == 3) > 0, ]
# [,1] [,2] [,3]
#[1,] 1 2 3
#[2,] 1 3 4
#[3,] 1 3 5
You can also use apply :
combs[apply(combs, 1, function(x) all(c(1, 3) %in% x)), ]

Subtract vector from one column of a matrix

I'm a complete R novice, and I'm really struggling on this problem. I need to take a vector, evens, and subtract it from the first column of a matrix, top_secret. I tried to call up only that column using top_secret[,1] and subtract the vector from that, but then it only returns the column. Is there a way to do this inside the matrix so that I can continue to manipulate the matrix without creating a bunch of separate columns?
Sure, you can. Here is an example:
m <- matrix(c(1,2,3,4),4,4, byrow = TRUE)
> m
[,1] [,2] [,3] [,4]
[1,] 1 2 3 4
[2,] 1 2 3 4
[3,] 1 2 3 4
[4,] 1 2 3 4
m[,4] <- m[,4] - c(5,5,5,5)
which gives:
> m
[,1] [,2] [,3] [,4]
[1,] 1 2 3 -1
[2,] 1 2 3 -1
[3,] 1 2 3 -1
[4,] 1 2 3 -1
Or another option is replace
replace(m, cbind(seq_len(nrow(m)), 4), m[,4] - 5)
data
m <- matrix(c(1,2,3,4),4,4, byrow = TRUE)

Repeat rows in a data frame according to a vector

I have a data frame and would like to repeat each row by each element in a pre defined vector.
for example if I have a matrix (I use matrix for example)
matrix(c(1,2,3,2,1,3),2)
[,1] [,2] [,3]
[1,] 1 3 1
[2,] 2 2 3
I would like this to return
matrix(c(1,1,2,2,3,3,2,2,1,1,3,3),4)
[,1] [,2] [,3]
[1,] 1 3 1
[2,] 1 3 1
[3,] 2 2 3
[4,] 2 2 3
if the vector was vec = c(2,2).
my vector has varying size elements. Sorry, I am new to coding.
Repeat over the row numbers. In your example:
base = matrix(c(1,2,3,2,1,3),2)
rows = 1:nrow(base)
index= rep(rows, c(2,2))
base[index,]

Nested for-loop skips loops

this is my problem:
I have a grid (see plot below), and I need to get and store in a list the coordinates of each vertex of each block (cell). The order of blocks that I need is '1-1', ... '4-1', '1-2', ... '4-2'. To keep it simple I'm just working with the indexes for now.
Based on two vectors with the common East and North coordinates I've written a little function, which is partially producing the output that I need. It is skipping the cell '1-2' and '2-2' (see output below). I can't see where exactly is the error, but I suspect that the issue is in my nested for loop. (There are many questions on for loop, but none helped me with my problem).
Any help will be appreciated and apologise if this is too basic to be asked here.
vectors:
x.breaks <- c(191789.1, 291789.1, 391789.1)
y.breaks <- c(5172287, 5272287, 5372287, 5472287, 5572287)
Function:
getting_vertices <- function(x.breaks, y.breaks){
xs <- list()
ys <- list()
polys <- list()
for(i in 1 : (length(x.breaks)-1)){
xs[[i]] <- c(i, i+1 , i+1, i, i)
}
for(j in 1 : (length(y.breaks)-1)){
ys[[j]] <- c(j, j, j+1, j+1, j)
}
for(v in 1 : length(sapply(ys, length)) ){
for(k in 1: length(sapply(xs, length))){
polys[[v*k]] <- cbind(xs[[k]], ys[[v]])
}
}
return(polys)
}
getting_vertices(x.breaks, y.breaks)
Output (this is partially correct):
[[1]]
[,1] [,2]
[1,] 1 1
[2,] 2 1
[3,] 2 2
[4,] 1 2
[5,] 1 1
[[2]]
[,1] [,2]
[1,] 1 2
[2,] 2 2
[3,] 2 3
[4,] 1 3
[5,] 1 2
[[3]]
[,1] [,2]
[1,] 1 3
[2,] 2 3
[3,] 2 4
[4,] 1 4
[5,] 1 3
[[4]]
[,1] [,2]
[1,] 1 4
[2,] 2 4
[3,] 2 5
[4,] 1 5
[5,] 1 4
[[5]]
NULL
[[6]]
[,1] [,2]
[1,] 2 3
[2,] 3 3
[3,] 3 4
[4,] 2 4
[5,] 2 3
[[7]]
NULL
[[8]]
[,1] [,2]
[1,] 2 4
[2,] 3 4
[3,] 3 5
[4,] 2 5
[5,] 2 4
The logic behind the line polys[[v*k]] <- ... is incorrect, for example, v=2, k=1 will overwrite v=1, k=2. There are no combinations of v and k that make 5 or 7, hence these entries are empty.
I expect that you meant to write something like:
polys[[v+(k-1)*(length(ys))]] <- ...
or
polys[[k+(v-1)*(length(xs))]] <- ...
depending on the order that you want your results in

How can I denominate levels of lists in R?

I would like to denominate the levels of a list, as with rownames() or colnames() when denominating rows and columns of matrices.
Example:
a<-matrix(rep(1,4),2,2)
b<-matrix(rep(2,9),3,3)
list<-list(a,b)
print(list)
Instead of returning [[1]] at the first level I want the list to use some string like 'matrix a' instead. Maybe this is simple to do.
Just use names:
names(list) = c("A","B")
> list
$A
[,1] [,2]
[1,] 1 1
[2,] 1 1
$B
[,1] [,2] [,3]
[1,] 2 2 2
[2,] 2 2 2
[3,] 2 2 2
list[["A"]]
[,1] [,2]
[1,] 1 1
[2,] 1 1
Note that in general it is not good practice to use R reserved words such as list as variable names.

Resources