Hey everyone, I have a large Matrix X with the dimensions (654x7095). I wanted to subset this matrix and replace the values of this subsetted matrix of X with another matrix which I have created. The R-code is as follows -
install.packages("Matrix")
install.packages("base")
library(Matrix)
library(base)
T = 215
n = 3
k = 33
X = matrix(0,T*n,T*k)
IN = diag(n)
K1 = Matrix(0, n*n, n*(n-1)/2, sparse = TRUE)
for(i in 1:(n-1)){
K1[(2+(i-1)*(n+1)):(i*n), (1+(i-1)*(n-i/2)):(i*(n-i)*(i+1)/2)] <- diag(n-i)
}
yin = matrix(rnorm(645), ncol = 3)
Xu = matrix(rnorm(2150), ncol = 10)
#Till yet I have defined the variables and matrices which will be used in subsetting.
Above codes are perfectly fine, however, the code below is showing error -
#Loop for X subsetting
for(i in 1:T){
X[(((i-1)*n)+1):(i*n), (((i-1)*k)+1):(i*k)] <- cbind( (t(kronecker(yin[i,],IN))%*%K1) , (t(kronecker(Xu[i,],IN))))
}
# in this Kronecker() finds the Kronecker tensor product of two Matrix A and B. This function can be used with the help of "base" library.
When I am running this above code, the error which is showing is -
Error in X[(((i - 1) * n) + 1):(i * n), ] <- cbind((t(kronecker(yin[i, :
number of items to replace is not a multiple of replacement length
However, when I am running this same command in MATLAB it is working perfectly fine. MATLAB CODE -
X = zeros(T*n,T*k);
for i = 1:T
X((i-1)*n+1:i*n,(i-1)*k+1:i*k) = [kron(yin(i,:),IN)*K1, kron(Xu(i,:),IN)];
end
The output which MATLAB is giving is that it fills up the values in number of rows and columns which is defined in the Loop for subsetting the X. I have attached the snapshot of the desired output which MATLAB is giving. However, error is showing in R for the same.
Can someone enlighten me as where I am going wrong with the R code?
I appreciate the help, Many thanks.
I think the problem is how the class 'dgeMatrix' is handled. Try
for (i in 1:T) {
X[(((i-1)*n)+1):(i*n), (((i-1)*k)+1):(i*k)] <- as.matrix(cbind((t(kronecker(yin[i,],IN))%*%K1) , (t(kronecker(Xu[i,],IN)))))
}
Related
I have an all zero sparse matrix K1 with the dimensions (9x3). I wanted to replace certain values of this matrix with an another matrix. Also, instead of numerical indexing, I have used variable indexing to make it more dynamic. The codes are as follows -
n <- 3
library(Matrix)
K1 <- Matrix(0, n*n, n*(n-1)/2, sparse = TRUE)
for (i in 1:(n - 1)) {
K1[2 + (i - 1)*(n + 1):i*n,
1 + (i - 1)*(n - i/2):i*(n - i)*(i + 1)/2] <- diag(n - i)
}
However, it shows the error -
Error in replCmat4(x, i1 = if (iMi) 0:(di[1] - 1L) else .ind.prep2(i, :
too many replacement values
Sometimes this error as well -
Error in intI(i, n = di[margin], dn = dn[[margin]], give.dn = FALSE) :
index larger than maximal 9
But, when I run the Similar code in MATLAB, it runs perfectly. MATLAB code -
n = 3
K1 = sparse(n*n,n*(n-1)/2);
for i = 1:n-1
K1(2+(i-1)*(n+1):i*n,1+(i-1)*(n-i/2):i*n-i*(i+1)/2) = eye(n-i);
end
And the output which MATLAB gives is -
K1 =
(2,1) 1.00
(3,2) 1.00
(6,3) 1.00
Thus, above is my desired output as well.
Can someone tell what is going wrong when I am trying to execute the same in R.
I appreciate the help. Thanks.
Please put the index in a pair of braket, otherwise they may be
explained differently in R and Matlab.
K1[(2+(i-1)*(n+1)):(i*n), (1+(i-1)*(n-i/2)):(i*(n-i)*(i+1)/2)]
I am trying to construct a for loop that solves for a list of variables in a data set.
However, once I run it, the code only seems to calculate the first variable.
for (t in 1:nTest){
m = DataTest$Item[t]
u = DataTest$User[t]
Sorted = sort(ItemSim[,m], decreasing = T,index.return=TRUE)
MostSim = Sorted$ix[1:N]
Wgts = ItemSim[MostSim,m]
DataTest$CosineItem = (t(Wgts) %*% UM.Item[MostSim,u])/sum(Wgts)
DataTest$CosineItem}
DataTest$CosineItem
Any help with this issue is greatly appreciated.
The CosineItem column is getting updated/replacing from each loop. If we are updating a particular row, then use the index
for (t in 1:nTest){
m <- DataTest$Item[t]
u <- DataTest$User[t]
Sorted <- sort(ItemSim[,m], decreasing = T,index.return=TRUE)
MostSim <- Sorted$ix[1:N]
Wgts <- ItemSim[MostSim,m]
DataTest$CosineItem[t] <- (t(Wgts) %*% UM.Item[MostSim,u])/sum(Wgts)
}
I have a data set with election poll data with numeric values 0-10.
I have 30 columns with these values and I want to compare every column with
all the other columns in order to create a correlation matrix.
]
But I keep getting the following error code:
Error in columnlist[i, j] <- cor(feeling_therm[, i], feeling_therm[, j], :
incorrect number of subscripts on matrix
Any suggestion on how to get this right? I'm still getting used to the syntax of R.
Just use cor(election). It should create the correlation matrix.
As Nathan Werth remarked, cor(election) works just fine. However, if you insist on using a for loop you should initialize your matrix as a matrix (including correct dimensions), not as a list:
election <- replicate(5, rnorm(n = 100))
election <- as.data.frame(election)
cor_matrix <- matrix(nrow = ncol(election), ncol = ncol(election))
for (i in 1:ncol(election)) {
for (j in 1:ncol(election)) {
cor_matrix[i,j] <- cor(election[,i], election[,j], use = "complete")
}
}
If your aim is to store values in a list then following is an option.
n_col <- ncol(election)
electionlist <- as.list(data.frame( matrix(NA, n_col, n_col)))
for (i in 1 : n_col) {
for (j in 1 : n_col) {
electionlist[[c(i, j)]] <- cor(election[,i],
election[,j], use = "complete")
}
}
I am trying to create a function that will take in a vector k and return to me a matrix with dimensions length(distMat[1,]) by length(k). distMat is a huge matrix and indSpam is a long vector. In particular to my situation, length(distMat[1,]) is 2412. When I enter in k as a vector of length one, I get a vector of length 2412. I want to be able to enter in k as a vector of length two and get a matrix of 2412x2. I am trying to use a while loop to let it go through the length of k, but it only returns to me a vector of length 2412. What am I doing wrong?
predNeighbor = function(k, distMat, indSpam){
counter = 1
while (counter<(length(k)+1))
{
preMatrix = apply(distMat, 1, order)
orderedMatrix = t(preMatrix)
truncate = orderedMatrix[,1:k[counter]]
checking = indSpam[truncate]
checking2 = matrix(checking, ncol = k[counter])
number = apply(checking2, 1, sum)
return(number[1:length(distMat[1,])] > (k[counter]/2))
counter = counter + 1
}
}
I am trying to create a function that will take in a vector k and return to me a matrix with dimensions length(distMat[1,]) by length(k)
Here's a function that does this.
foo <- function(k, distMat) {
return(matrix(0, nrow = length(distMat[1, ]), ncol = length(k)))
}
If you have other requirements, please describe them in words.
Based on your comment, I think I understand better your goal. You have a function that returns a vector of length k and you want to save it's output as rows in a matrix. This is a pretty common task. Let's do a simple example where k starts out as 1:10, and say we want to add some noise to it with a function foo() and see how the rank changes.
In the case where the input to the function is always the same, replicate() works very well. It will automatically put everything in a matrix
k <- 1:10
noise_and_rank <- function(k) {
rank(k + runif(length(k), min = -2, max = 2))
}
results <- replicate(n = 8, expr = {noise_and_rank(k)})
In the case where you want to iterate, i.e., the output from the one go is the input for the next, a for loop is good, and we just pre-allocate a matrix with 0's, to fill in one column/row at a time
k <- 1:10
n.sim <- 8
results <- matrix(0, nrow = length(k), ncol = n.sim)
results[, 1] <- k
for(i in 2:n.sim) {
results[, i] <- noise_and_rank(results[, i - 1])
}
What your original question seems to be about is how to do the pre-allocation. If the input is always the same, using replicate() means you don't worry about it. If the input is is different each time, then pre-allocate using matrix(), you don't need to write any special function.
Here is the formula which I am trying to calculate in R.
So far, this is my approach using a simplified example
t <- seq(1, 2, 0.1)
expk <- function(k){exp(-2*pi*1i*t*k)}
set.seed(123)
dat <- ts(rnorm(100), start = c(1994,3), frequency = 12)
arfit <- ar(dat, order = 4, aic = FALSE) # represent \phi in the formula
tmp1 <- numeric(4)
for (i in seq_along(arfit$ar)){
ek <- expk(i)
arphi <- arfit$ar[i]
tmp1[i] <- ek * arphi
}
tmp2 <- sum(tmp1)
denom = abs(1-tmp2)^2
s2 <- t/denom
Error : Warning message:
In tmp1[i] <- ek * arphi :
number of items to replace is not a multiple of replacement length
I was trying to avoid using for loop and tried using sapply as in solutions to this question.
denom2 <- abs(1- sapply(seq_along(arfit$ar), function(x)sum(arfit$ar[x]*expf(x))))^2
but doesnt seem to be correct. The problem is to do the sum of the series(over index k) when it is taking values from another vector as well, in this case, t which is in the numerator.
Any solutions ?
Any suggestion for a test dataset, maybe using 0 and 1 to check if the calculation is done correctly in this loop here ?
Typing up the answer determined in chat. Here's a solution involving vapply.
First correct expk to:
expk <- function(k){sum(exp(-2*pi*1i*t*k))}
Then you can create this function and vapply it:
myFun <- function(i) return(expk(i) * arfit$ar[i])
tmp2 <- sum(vapply(seq_along(arfit$ar), myFun, complex(1)))