Simulation Study Calling Function - r

I spend multiple hours of thinking about the following problem. I am running a simulation study and I want to define functions outside the simulation study in order to be able to call these functions in the end of my code.
This example illustrates the problem, but is not replicable (below you will find a replicable example of the problem). I make use of the "metafor" package for doing a meta-analysis.
I would like to use the following function that I define outside my final simulation code:
mat <- matrix(NA, nrow = 8, ncol = 3)
funtr.stu <- function(i) {
for (y in 1:8) {
mat[y,i] <- tr[[y]]$k0
}
return(mat)
}
"tr" is a list and consists of the results of 8 times an analysis. I want to retrieve the object "k0" from that list and store it into the matrix "mat".
In the following part of the code (in which I run the simulation), I want to call the function and fill the matrix "mat" with the correct numbers.
for (i in 1:iterations) {
tr.stu <- funtr.stu()
}
The result of this code is a filled matrix, but within each column the same numbers. Thus, R isn´t storing the numbers every iteration, but stores only the last iteration.
How can I modify my code in such a way that R is storing the output as I want?
A very simplified example:
Mat represents just a matrix with numbers and res is an empty matrix that I want to fill.
mat <- matrix(data = c(1,2,3,4,5,6), ncol = 2, nrow = 3)
res <- matrix(NA, ncol = 2, nrow = 3)
I use the function "fun" to fill the empty matrix res.
fun <- function() {
for (i in 1:2) {
res[y,i] <- mat[y,i]
}
return(res)
}
This is what I would like to put in the end of my code (I just want to call the function and with this function I want to fill the matrix "res"). However, if I use the code below R only fills the third row and not the first and second row.
for (y in 1:3) {
test <- fun()
}
Thank you in advance!

This should work in your case. Basically, return one row in each iteration of the for loop. Where as you are returning the entire 'res' matrix.
mat <- matrix(data = c(1,2,3,4,5,6), ncol = 2, nrow = 3)
res <- matrix(NA, ncol = 2, nrow = 3)
fun <- function() {
for (i in 1:2) {
res[y,i] <- mat[y,i]
}
return(res[y,])
}
for (y in 1:3) {
test[y,] <- fun()
}

Related

Is there another way to write the following function without the for loop in R?

I am trying to write the following function without the for loop. Note that I am trying to replicate the function diag().
selfdiag <- function(a) {
j <- c()
for (i in 1:ncol(a)) {
j[i] <- a[i, i]
}
return(j)
}
Consider that:
mat <- matrix(rnorm(4), ncol = 2)
The function selfdiag() should create the same result as diag().
Thanks for any help on this.
You can create a data frame with the row and column indices for the diagonal and use it to extract the diagonal values from the matrix.
mat <- matrix(rnorm(4), ncol = 2)
The diag() way to do it -
diag(mat)
[1] -0.5004046 -0.8785558
The other way to do it -
rows_cols <- data.frame(rows = c(1:ncol(mat)), cols = c(1:ncol(mat)))
mat2 <- mat[as.matrix(rows_cols)]
mat2
[1] -0.5004046 -0.8785558
Hope this helps!

How to create matrix of all 2^n binary sequences of length n using recursion in R?

I know I can use expand.grid for this, but I am trying to learn actual programming. My goal is to take what I have below and use a recursion to get all 2^n binary sequences of length n.
I can do this for n = 1, but I don't understand how I would use the same function in a recursive way to get the answer for higher dimensions.
Here is for n = 1:
binseq <- function(n){
binmat <- matrix(nrow = 2^n, ncol = n)
r <- 0 #row counter
for (i in 0:1) {
r <- r + 1
binmat[r,] <- i
}
return(binmat)
}
I know I have to use probably a cbind in the return statement. My intuition says the return statement should be something like cbind(binseq(n-1), binseq(n)). But, honestly, I'm completely lost at this point.
The desired output should basically recursively produce this for n = 3:
binmat <- matrix(nrow = 8, ncol = 3)
r <- 0 # current row of binmat
for (i in 0:1) {
for (j in 0:1) {
for (k in 0:1) {
r <- r + 1
binmat[r,] <- c(i, j, k)}
}
}
binmat
It should just be a matrix as binmat is being filled recursively.
I quickly wrote this function to generate all N^K permutations of length K for given N characters. Hope it will be useful.
gen_perm <- function(str=c(""), lst=5, levels = c("0", "1", "2")){
if (nchar(str) == lst){
cat(str, "\n")
return(invisible(NULL))
}
for (i in levels){
gen_perm(str = paste0(str,i), lst=lst, levels=levels)
}
}
# sample call
gen_perm(lst = 3, levels = c("x", "T", "a"))
I will return to your problem when I get more time.
UPDATE
I modified the code above to work for your problem. Note that the matrix being populated lives in the global environment. The function also uses the tmp variable to pass rows to the global environment. This was the easiest way for me to solve the problem. Perhaps, there are other ways.
levels <- c(0,1)
nc <- 3
m <- matrix(numeric(0), ncol = nc)
gen_perm <- function(row=numeric(), lst=nc, levels = levels){
if (length(row) == lst){
assign("tmp", row, .GlobalEnv)
with(.GlobalEnv, {m <- rbind(m, tmp); rownames(m) <- NULL})
return(invisible(NULL))
}
for (i in levels){
gen_perm(row=c(row,i), lst=lst, levels=levels)
}
}
gen_perm(lst=nc, levels=levels)
UPDATE 2
To get the expected output you provided, run
m <- matrix(numeric(0), ncol = 3)
gen_perm(lst = 3, levels = c(0,1))
m
levels specifies a range of values to generate (binary in our case) to generate permutations, m is an empty matrix to fill up, gen_perm generates rows and adds them to the matrix m, lst is a length of the permutation (matches the number of columns in the matrix).

How to fill in matrix inside of foreach loop?

I would like to fill in the matrix in inside of the parallel loop.
When I call the function, it returns back me the empty matrix
I was wondering whether can someone help me with that.
Compute_TaskSimilarity<-function(X,...){
Task_similarity<-matrix(0,nrow=100,ncol=100)
foreach(i = 1:K, .combine = "cbind") %dopar% {
for (j in (i + 1):(ncol(Task_similarity))) {
Myvalue<- ComputeValue
if (Myvalue!=0){
TaskSimilarity[i, j] <- Myvalue
} else{
TaskSimilarity[i, j] <- 0.0
}
}
return(TaskSimilarity)
}
Maybe do something like this: create a data.frame of all combinations of indices, then apply over all combinations, then reshape into a matrix of the right size. (I added a simple multiplication as example for a more complex operation and used a smaller array of lenght 10):
indices <- data.frame(x=rep(1:10, each=10), y=rep(1:10, 10))
result <- foreach(i=1:nrow(indices)) %dopar% {
# just an example for a more complex calculation
indices$x[i] * indices$y[i]
}
result <- do.call(c, result)
dim(result) <- c(10, 10)

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))

Edit: R simulation study calling function

I spend multiple hours of thinking about the following problem. I am running a simulation study and I want to define functions outside the simulation study in order to be able to call these functions in the end of my code.
A very simplified example:
Mat represents just a matrix with numbers and res is an empty matrix that I want to fill.
mat <- matrix(data = c(1,2,3,4,5,6), ncol = 2, nrow = 3)
res <- matrix(NA, ncol = 2, nrow = 3)
I use the function "fun" to fill the empty matrix res.
fun <- function() {
for (i in 1:2) {
res[y,i] <- mat[y,i]
}
return(res)
}
This is what I would like to put in the end of my code (I just want to call the function and with this function I want to fill the matrix "res"). However, if I use the code below R only fills the third row and not the first and second row.
for (y in 1:3) {
test <- fun()
}
My question is: why isn't R also filling the first and second row and how can I change my code in such a way that R provides me with the desired result?
Thank you in advance!
EDIT:
The following example also illustrates my problem. I make use of the "metafor" package for doing a meta-analysis.
I would like to use the following function that I define outside my final simulation code:
mat <- matrix(NA, nrow = 8, ncol = 3, dimnames = list(c("0_le", "0_ri", ".13_le", ".13_ri", ".33_le", ".33_ri", ".5_le", ".5_ri"), c("1", "2", "3")))
funtr.stu <- function(i) {
for (y in 1:8) {
mat[y,i] <- tr[[y]]$k0
}
return(mat)
}
"tr" is a list and consists of the results of 8 times an analysis. I want to retrieve the object "k0" from that list and store it into the matrix "mat".
In the following part of the code (in which I run the simulation), I want to call the function and fill the matrix "mat" with the correct numbers.
for (i in 1:iterations) {
kip <- funtr.stu()
}
The result of this code is a filled matrix, but within each column the same numbers. Thus, R isn´t storing the numbers every iteration, but stores only the last iteration.
How can I modify my code in such a way that R is storing the output as I want?
Thank you in advance for your help!
It is because you are overwriting all values of the matrix test in each iteration. I added print(test) in the loop. See the code.
mat <- matrix(data = c(1,2,3,4,5,6), ncol = 2, nrow = 3)
res <- matrix(NA, ncol = 2, nrow = 3)
mat
res
fun <- function() {
for (i in 1:2) {
res[y,i] <- mat[y,i]
}
return(res)
}
for (y in 1:3) {
test <- fun()
print(test)
}
This should work in your case. Basically, return one row in each iteration of the for loop. Where as you are returning the entire 'res' matrix.
mat <- matrix(data = c(1,2,3,4,5,6), ncol = 2, nrow = 3)
res <- matrix(NA, ncol = 2, nrow = 3)
fun <- function() {
for (i in 1:2) {
res[y,i] <- mat[y,i]
}
return(res[y,])
}
for (y in 1:3) {
test[y,] <- fun()
}

Resources