Assign and use variable during for loop in R - r

I have the a dataset, containing about 4000 matrices in vector form, each of them should be named by the date it was created.
Right now I have the following:
dates <- unique(rcov_matrix$dateid)
for(k in dates){
k <- matrix(0, 30, 30)
for(i in 1:30){
for (j in 1:i){
number <- number + 1
value <- rcov_matrix[1, number]
k[i,j] <- value
k[j,i] <- value
}
}
}
The code correctly assigns the entries of the vector to the matrix, but I only end up with one matrix named k in the end.
I understand that this is because of the way variable names are assigned in R, but I could not find a viable solution for my problem in similar posts.
assign(k, matrix(0, 30, 30))
does not work because I have to reuse the variable name later in the next for loop.
How can I solve this? Or is there a more effective way to assign my values to the matrices?
Thank you.

Maybe the simplest is to use assign at the end of the loop, rather than the start.
for (k in dates){
This_k <- matrix(0, 30, 30)
for(i in 1:30){
for (j in 1:i){
value <- rnorm(1) # I use rnorm here to make the example reproducible
This_k[i,j] <- value
This_k[j,i] <- value
}
}
assign(k, This_k)
}
Alternatively (and perhaps a little more efficient), you could put your matrices in a list and use list indexing:
klist = lapply(rep(0, length(dates)), matrix, 30, 30)
names(klist) = dates
for (k in dates){
for(i in 1:30){
for (j in 1:i){
value <- rnorm(1)
klist[[k]][i,j] <- value
klist[[k]][j,i] <- value
}
}
}

Related

List giving an empty values upto penultimate cell

following is the code i am trying to run.The main objective is to run the model for different K values then after calculate the accuracies in order to choose the best K value.
so i thought of using for loop where every model.Result and the respective accuracy is stored in lists.,then after is sent out with respective k values..
but the thing is for the following code...the list isnt having any values from 1:29 and there is predicted values for 30..
k = 1:30
for(l in k){
pre[[l]] = knn(train_dataset,test_dataset,cl = labels_train, k = l)
}
output :
enter image description here
can someone help me out with this....like why the list is coming like that and what should be done in order to get the correct result..and why so..?
Here is a solution, with the models fit using the code in tacoman's comment.
library(class)
set.seed(1) # Make the results reproducible
knn_list <- lapply(1:30, function(l){
knn(train_dataset, test_dataset, cl = labels_train, k = l)
})
ok <- sapply(knn_list, '==', labels_test)
acc <- colMeans(ok)
which(acc == max(acc))
plot(acc, type = "b")
The for loop in the question can also be run, as long as the results list is created beforehand. The results are identical.
set.seed(1) # Make the results reproducible
k <- 1:30
pre <- vector("list", length = 30)
for(l in k){
pre[[l]] <- knn(train_dataset, test_dataset, cl = labels_train, k = l)
}
identical(pre, knn_list)
#[1] TRUE
Example data
set.seed(2021)
n <- nrow(iris)
i <- sample(n, 0.7*n)
train_dataset <- iris[i, -5]
test_dataset <- iris[-i, -5]
labels_train <- iris[i, 5]
labels_test <- iris[-i, 5]

for loop question in r :number of items to replace is not a multiple of replacement length

all
I'm new to R. I try many ways and still cannot solve it. Can anyone help to check??
I am trying to produce 3 times 100 random values that follow a chisquare distribution. Console says ''number of items to replace is not a multiple of replacement length''. Any hint to fix it??
for(i in 1:3) {
x1[i] <- rchisq(100, df=2)
n1[i] <- length(x1[i])
}
As an explanation for your problem: You are trying to store a vector of 100 elements into a single element, the ith element, of a vector, x1. To illustrate, you could put a vector of values into a vector of the same length:
x <- rnorm(6, 0, 1)
x[1:3] <- c(1,2,3)
x
## [1] 1.0000000 2.0000000 3.0000000 -0.8652300 1.3776699 -0.8817483
You could to store them into a list, each element of a list is a vector that can be of any length. You will need double square brackets.
x1 <- list()
for(i in 1:3) {
x1[[i]] <- rchisq(100, df=2)
n1[i] <- length(x1[[i]])
}
Lists and vectors are different types of data structures in R, you can read a lot about them in advanced R.
It depends on what containers you want to use. There are two containers that come to mind, either a list or matrix.
# list format
x1 = list();
n1 = vector();
for(i in 1:3) {
x1[[i]] <- rchisq(100, df=2)
n1[i] <- length(x1[[i]])
}
note the double brackets [[i]] as mentioned in the comments
# matrix format
x1 = matrix(NA, nrow = 100, ncol = 3)
n1 = vector();
for(i in 1:3) {
x1[,i] <- rchisq(100, df=2)
n1[i] <- length(x1[,i])
}

Populating a vector with a for loop

I am trying to fill a vector pred_pos with the result pred on each iteration of the for loop. However, my pred_pos vector is never filled. The my_vec object is a list of large character vectors which I don't believe needs to be reproduced for this problem as it is most likely a fundamental indexing error. I just need to know how to populate a vector from this for loop. I can't seem to work out a solution.
pred_pos <- vector("numeric" , 2)
for(i in my_vec) {
for(r in pred_pos) {
inserts <- sapply(i, function(n) { n <- cond_probs_neg[n] } )
pred <- sum(unlist(inserts) , na.rm = T) * apriori_neg
pred_pos[r] <- pred
}
}
Assuming that the rest of your code works, there is no need to explicitly state:
pred_pos <- vector("numeric" , 2)
That creates a numeric vector of length two. You ought to be able to write:
pred_pos <- vector()
Now when you wish to append to the vector you can simply use:
vector[length(vector)+1] <- someData
I believe your code should work if it is adjusted:
pred_pos <- vector()
for(i in my_vec) {
inserts <- sapply(i, function(n) { n <- cond_probs_neg[n] } )
pred <- sum(unlist(inserts) , na.rm = T) * apriori_neg
pred_pos[length(pred_pos)+1] <- pred
}

General code for a summation in R

I'm writing some code in R and I came across following problem:
Basically, I want to calculate a variable X[k], where X takes on values for each k, like this:
where A is a known variable which takes on different values for each index.
For the moment, I have something like this:
k <- NULL
X <- NULL
z<- 1: n
for (k in seq(along =z)){
for (j in seq (along = 1:k)){
X[k] = 1/k*sum(A[n-k]/A[n-j+1])
}
}
which can't be right. Any idea on how to fix this one?
As always, any help would be dearly appreciated.
Try this
# define A
A <- c(1,2,3,4)
n <- length(A)
z <- 1:n
#predefine X (don't worry, all values will be overwritten, but it will have the same length as A
X <- A
for(k in z){
for(j in 1:k){
X[k] = 1/k*sum(A[n-k]/A[n-j+1])
}
}
You don't need to define z, it is only used inside the for. In this case, do for(k in 1:n){
As
You can do the following
set.seed(42)
A <- rnorm(10)
k <- sample(length(A), 4)
calc_x <- function(A, k){
n <- length(A)
c_sum <- cumsum(1/rev(A)[1:max(k)])
A[n-k]/k * c_sum[k]
}
calc_x(A,k)
what returns:
[1] 0.07775603 2.35789999 -0.45393983 0.13323284

R: Artificial set generation

I would like to generate the set with growing number of some representative.
In final I need a matrix or a data.frame, consisting of 100 rows containing i number of representative (in example it's 1). But there is a following error. What is the trick? What I am missing?
Error: no function to return from, jumping to top level
for(i in 1:100) {
x <- c(rep(1,i),rep(100000,(2500-i)))
return(x)
}
Many thanks!
You can only use return within a function. One solution is to create a matrix to store the results in, something like this:
R> m = matrix(0, ncol=100, nrow=2500)
R>
R> for(i in 1:100) {
+ m[,i] = c(rep(1, i), rep(100000, (2500-i)))
+ }
should do the trick. Or using the sapply function:
m1 = sapply(1:100, function(i) c(rep(1, i), rep(100000,(2500-i))))
For info, your rep function can also be simplified to:
rep(c(1, 1000000), c(i, 2500-i))

Resources