I have a large array with dimensions data[1:10,1:50,1:1000]. I would like to swap out the 5th row of all the matrices with new data with the dimensions new_data[1,1:50,1:1000].
So far I have tried to pull the array apart and put it back together:
data1<-data[1:4,1:50,1:1000]
data2<-data[6:10,1:50,1:1000]
combined_data<-rbind(data1,new_data,data2)
However rbind doesn't seem to be appropriate here and returns a large matrix rather than a large array with dimensions[1:10,1:50,1:1000]
On request here is a simple example:
vec1<-1:4
vec2<-c(1,2,2,4,1,2,2,4)
data_array<-array(c(vec1,vec2),dim=c(4,3,10))
data_array[,,1] # visualizing one of the 10 matrix - say they error is in row 3 where we would expect all 3s
new_data<-array(c(3,3,3),dim=c(1,3,10))
new_data[,,1] # correct data that we want to swap into row 3 of all the matrices
array2<-data_array[1:2,,] #correct data from original array
array3<-array(data_array[4,,],dim=c(1,3,10)) #correct data from original array
combined_data <- rbind(array2,new_data,array3) # attempting to combine and new_data into the correct row
However this results in a data with the dimensions [1:3,1:60], where I am aiming for the exact same dimensions as the original data_array ([1:4,1:3,1:10]) but with the new_data swapped in at row 3 of each matrix
Try with abind from "abind" package.
library(abind)
array4 <- abind(array2,new_data,along=1)
final_data <- abind(array4,array3,along=1)
The reference is as follows:
http://math.furman.edu/~dcs/courses/math47/R/library/abind/html/abind.html
Since an array is really just a vector with dimensions, you can replace every 4th value (the number of rows in each stratum), starting at the 3rd value (the row you want to replace), with the new_data
data_array[seq(3, by=dim(data_array)[1], to=length(data_array))] <- new_data
data_array
#, , 1
#
# [,1] [,2] [,3]
#[1,] 1 1 1
#[2,] 2 2 2
#[3,] 3 3 3
#[4,] 4 4 4
#
#, , 2
#
# [,1] [,2] [,3]
#[1,] 1 1 1
#[2,] 2 2 2
#[3,] 3 3 3
#[4,] 4 4 4
#...
Related
When combining a data frame and a vector with different number of rows/lengths, bind_cols gives an error, whereas cbind repeats rows – why is this?
(And is it really wise to have that as a default behavior of cbind?)
See example data below.
# Example data
x10 <- c(1:10)
y10 <- c(1:10)
xy10 <- tibble(x10, y10)
z20 <- c(1:20)
# get an error
xyz20 <- dplyr::bind_cols(xy10, z20)
# why does cbind repeat rows of xy10 to suit z20?
xyz20 <- cbind(xy10, z20)
xyz20
base::cbind is a generic function. Its behavior is different for matrix and data frames.
For matrices, it does warn if objects have different number of rows (see more on Note below).
cbind(as.matrix(xy10), z20)
# x10 y10 z20
# [1,] 1 1 1
# [2,] 2 2 2
# [3,] 3 3 3
# [4,] 4 4 4
# [5,] 5 5 5
# [6,] 6 6 6
# [7,] 7 7 7
# [8,] 8 8 8
# [9,] 9 9 9
#[10,] 10 10 10
#Warning message:
#In cbind(as.matrix(xy10), z20) :
# number of rows of result is not a multiple of vector length (arg 2)
But for data frames, it actually creates a data frame from scratch. So the following is identical, both giving a data frame of 20 rows:
cbind(xy10, z20)
## in this way, R's recycling rule steps in
data.frame(xy10[, 1], xy10[, 2], z20)
From ?cbind:
The ‘cbind’ data frame method is just a wrapper for ‘data.frame(..., check.names = FALSE)’. This means that it will split matrix columns in data frame arguments, and convert character columns to factors unless ‘stringsAsFactors = FALSE’ is specified.
Note: In non-data.frame cases, matrices are not allowed to grow bigger. Only vectors will be recycled or truncated.
## handling two vectors
## vector of shorter length is recycled
cbind(1:2, 1:4)
# [,1] [,2]
#[1,] 1 1
#[2,] 2 2
#[3,] 1 3
#[4,] 2 4
## handling two matrices
## has strict requirement on dimensions
cbind(as.matrix(1:2), as.matrix(1:4))
#Error in cbind(as.matrix(1:2), as.matrix(1:4)) :
# number of rows of matrices must match (see arg 2)
## handling a matrix and a vector
## vector of shorter length is recycled
cbind(1:2, as.matrix(1:4))
# [,1] [,2]
#[1,] 1 1
#[2,] 2 2
#[3,] 1 3
#[4,] 2 4
## handling a matrix and a vector
## vector of longer length is truncated
cbind(as.matrix(1:2), 1:4)
# [,1] [,2]
#[1,] 1 1
#[2,] 2 2
#Warning message:
#In cbind(1:4, as.matrix(1:2)) :
# number of rows of result is not a multiple of vector length (arg 1)
From ?cbind:
If there are several matrix arguments, they must all have the same number of rows....
If all the arguments are vectors, ..., values in shorter arguments are recycled to achieve this length...
When the arguments consist of a mix of matrices and vectors, the number of rows of the result is determined by the number of rows of the matrix arguments... vectors... are recycled or subsetted to achieve this length.
I want to produce a matrix which holds all possible combinations of a vector x of integers from 1 to the respective number.
The length of the vector x may change.
For this sample vector:
x = c(3,8,2)
I want the result to look something like this:
[,1] [,2] [,3]
[1,] 1 1 1
[2,] 1 1 2
[3,] 1 2 1
...
[48,] 3 8 2
I understand expand.grid does the job, however, I can't seem to find the parameters which allow for different sets in each column.
We get the sequence of each element (seq) and do expand.grid
out <- expand.grid(lapply(x, seq))
dim(out)
#[1] 48 3
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 need to create a function (x,k), were x= vector of length n, and k=integer.
The function needs to give me a matrix of dimensions [n x k], and the entries in each column need to be raised to the power of the number of that column (ie. in column one the entries are x, in column 2 the entries are x^2, etc).
I'm having a hard time figuring it out how to structure a function that would do this type of operation by column.
Thank you so much.
Something like this probably, taking advantage of outer, which returns a matrix as a result of applying a function to the two vectors.
matpower <- function(x,k) outer(x,seq_len(k),`^`)
matpower(1:4,4)
# [,1] [,2] [,3] [,4]
#[1,] 1 1 1 1
#[2,] 2 4 8 16
#[3,] 3 9 27 81
#[4,] 4 16 64 256
As fast as possible, I would like to replace the first zeros in some rows of a matrix with values stored in another vector.
There is a numeric matrix where each row is a vector with some zeros.
I also have two vectors, one containing the rows, in what to be replaced, and another the new values: replace.in.these.rows and new.values. Also, I can generate the vector of first zeroes with sapply
mat <- matrix(1,5,5)
mat[c(1,8,10,14,16,22,14)] <- 0
replace.in.these.rows <- c(1,2,3)
new.values <- c(91,92,93)
corresponding.poz.of.1st.zero <- sapply(replace.in.these.rows,
function(x) which(mat [x,] == 0)[1] )
Now I would like something that iterates over the index vectors, but without a for loop possibly:
matrix[replace.in.these.rows, corresponding.poz.of.the.1st.zero ] <- new.values
Is there a trick with indexing more than simple vectors? It could not use list or array(e.g.-by-column) as index.
By default R matrices are a set of column vectors. Do I gain anything if I store the data in a transposed form? It would mean to work on columns instead of rows.
Context:
This matrix stores contact ID-s of a network. This is not an adjacency matrix n x n, rather n x max.number.of.partners (or n*=30) matrix.
The network uses edgelist by default, but I wanted to store the "all links from X" together.
I assumed, but not sure if this is more efficient than always extract the information from the edgelist (multiple times each round in a simulation)
I also assumed that this linearly growing matrix form is faster than storing the same information in a same formatted list.
Some comments on these contextual assumptions are also welcome.
Edit: If only the first zeros are to be replace then this approach works:
first0s <-apply(mat[replace.in.these.rows, ] , 1, function(x) which(x==0)[1])
mat[cbind(replace.in.these.rows, first0s)] <- new.values
> mat
[,1] [,2] [,3] [,4] [,5]
[1,] 91 1 1 0 1
[2,] 1 1 1 1 92
[3,] 1 93 1 1 1
[4,] 1 1 0 1 1
[5,] 1 0 1 1 1
Edit: I thought that the goal was to replace all zeros in the chosen rows and this was the approach. A completely vectorized approach:
idxs <- which(mat==0, arr.ind=TRUE)
# This returns that rows and columns that identify the zero elements
# idxs[,"row"] %in% replace.in.these.rows
# [1] TRUE TRUE FALSE FALSE TRUE TRUE
# That isolates the ones you want.
# idxs[ idxs[,"row"] %in% replace.in.these.rows , ]
# that shows what you will supply as the two column argument to "["
# row col
#[1,] 1 1
#[2,] 3 2
#[3,] 1 4
#[4,] 2 5
chosen.ones <- idxs[ idxs[,"row"] %in% replace.in.these.rows , ]
mat[chosen.ones] <- new.values[chosen.ones[,"row"]]
# Replace the zeros with the values chosen (and duplicated if necessary) by "row".
mat
#---------
[,1] [,2] [,3] [,4] [,5]
[1,] 91 1 1 91 1
[2,] 1 1 1 1 92
[3,] 1 93 1 1 1
[4,] 1 1 0 1 1
[5,] 1 0 1 1 1