How do I ask R to compile a matrix column by column? - r

I am trying to generate a matrix sz by first applying a binomial, then adding values from the corresponding column of pombe_new_subs and this combined value being input as size for the following column.
After many frustrations, the following code is what I've ended up with and it just doesn't work - problems I'm coming across are;
# Error in sz[j, i + 1] = sz[, i] + pombe_new_subs[, i] :
# number of items to replace is not a multiple of replacement length
pombe_new_subs <- rmultinom(3, 15, prob = c(0.3, 0.3, 0.3))
randomdiv <- function(nchrom, ndivs, size) {
sz <- matrix(nrow = nchrom, ncol = ndivs)
for (j in 1:nchrom) {
n <- size
for (i in 1:ndivs) {
n <- rbinom(1, n, 0.5)
sz[j,i] <- n
}
sz[j,i+1] = sz[ ,i] + pombe_new_subs[ ,i]
sz[j, i+1] <- n
}
return (sz)
}
randomdiv(3, 3, 10)
I know this is probably a fairly simple looping exercise but frustration has entirely taken over.

Related

Repeated sampling until condition

I am looking to sample repeatedly from a distribution with a specific condition.
I am sampling 50 values for four iterations and saving the results. However I need each individual results from the iteration to be smaller than the last result at the same position.
mu.c <- c(7,6,5,3) # Means of control chains
chains.sim <- function(vector, N) {
all.list <- list()
for (i in 1:length(vector)) {
Y <- MASS::rnegbin(n = N, mu = vector[i], theta = 4)
name <- paste('position:',i, sep = '')
all.list[[name]] <- Y
}
all.list
}
chains.sim(mu.c, 50)
The sampling part works fine, but the Y individual results are of course not always smaller than the results from the previous iteration ("position").
Is there a way to repeat the sampling process until the result is smaller?
I would really appreciate your help!
I would add a while loop inside your for loop which samples data sets until the condition is met.
mu.c <- c(7,6,5,3) # Means of control chains
chain.sim <- function(vector, N) {
all.list <- list()
all.list[[1]] <- MASS::rnegbin(n = N, mu = vector[1], theta = 4)
for (i in 2:length(vector)) {
is_smaller <- FALSE
while(!is_smaller){
Y <- MASS::rnegbin(n = N, mu = vector[i], theta = 4)
if (all(all.list[[i-1]] >= Y)) is_smaller <- TRUE
}
all.list[[i]] <- Y
}
all.list
}
chain.sim(mu.c, 3)
Note that I changed the condition to >=, because if 0 is generated in any round, it will never find smaller values. Also, with 50 elements this code will never stop, because it is really unlikely to get two samples where each value is smaller, let alone 4 different samples.
Edit:
it can be much faster by sampling individually as you pointed out
chain.sim <- function(vector, N) {
all.list <- list()
all.list[[1]] <- MASS::rnegbin(n = N, mu = vector[1], theta = 4)
for (i in 2:length(vector)) {
Y <- numeric(N)
for (j in 1:N){
previous_value <- all.list[[i-1]][j]
if (previous_value == 0){
Y[j] = 0
next
}
is_smaller <- FALSE
while(!is_smaller){
val <- MASS::rnegbin(1, mu = vector[i], theta = 4)
if (val <= previous_value) is_smaller <- TRUE
Y[j] <- val
}
}
all.list[[i]] <- Y
}
all.list
}
chain.sim(mu.c, 50)
If 0 is encountered anywhere, no more simulation is necessary as we know the next value can only be 0. This makes the simulation much faster

R match/compare two matrix in R but loop seems doesn't work well

N = 4
comN <- gtools::permutations(2, N, v = c(0, 1), repeats = TRUE)
comstate <- matrix (NA, N, N)
for (i in 1:2^N) {
for (j in 1:N) {
comstate[1:N, ] = comN[i, ] # spoint<-comN[i,]
tcomstate = t(comstate) # need transpose "comstate" to ensure col stands for the component state
tcomstate[j, j] = (1 - comN[i, j])
y <- which(colSums(t(comN) == tcomstate[j, ]) == ncol(comN))
}
}
y
I tried to get y manually, (i=3)comN[3,], it works well, y=1,4,7,15 but when I go back to the loop, it is only 15, it need to be four values 1,4,7,15

How to run for loop R program faster?

I am using the following r code to compute the loglikelihood for left side and right side for each i = 1,2,...,200.
But I want to do this procedure for large number of generated dataset, for instance a = 10000 and iterate the entire loop for 1000 times. How can I speed up the the following program? Am I able to use applyfunction instead of for function?
Thank you in advance!
n1 = 100
n2 = 100
a = 1000
n= n1 + n2
# number of simulated copies of y
sim.data = matrix(NA, nrow = n, ncol = a)
for (i in 1:a) {
#for(j in 1:a){
sim.data[,i] = c(rnorm(n1, 2, 1), rnorm(n-n1, 4, 1))
#}
}
dim(sim.data)
# Compute the log-likelihood
B = ncol(sim.data)
loglike_profb = matrix(NA, n - 1, B)
for (j in 1:B) {
for (i in 1:(n - 1)) {
loglike_profb[i, j] = -0.5*(sum(((sim.data[1:i,j]) - mean(sim.data[1:i,j]))^2) + sum(((sim.data[(i + 1):n,j]) - mean(sim.data[(i +1):n,j]))^2))
}
}
You can put the calculation of the loglike_profb into a function and then use mapply
loglike_profb_func <- function(i,j){
-0.5*(sum(((sim.data[1:i,j]) - mean(sim.data[1:i,j]))^2) + sum(((sim.data[(i + 1):n,j]) - mean(sim.data[(i +1):n,j]))^2))
}
mapply(loglike_profb_func, rep(1:(n-1),B), rep(1:B,(n-1)))

How to regenerate fresh matrix when replicating

I have the following script:
randomdiv <- function(ncells, ndivs, size, accuracy) { sz <- matrix(nrow = ncells, ncol = ndivs)
for (j in 1:ncells) {
total_subunits <- size
for (i in 1:ndivs)
{
accurate_subunits <- (size * accuracy)
random_subunits <- round(size - accurate_subunits)
random_inh <- rbinom(1, random_subunits, 0.5)
accurate_inh <- (accurate_subunits / 2)
total_inh <- 2 * (random_inh + accurate_inh)
sz[j,i] <- total_inh
total_subunits <- total_inh
}
}
return (do.call(rbind, replicate(100, sz, simplify = FALSE)))
}
Such that I thought randomdiv(5, 20, 10, 0) would return a matrix with 500 rows, where the original sz matrix had been replicated 100 times. In fact, this is the case. However, the replicates are identical rather than each replicate being a fresh generation of data, which is what I need.
Any ideas how I can make sure that each replicate is a new matrix, not literally a replicate of the first one to be generated?

replacement and two for loop in R

I would like to have a vector res with length 200, which includes 20 times repetition of random generation values divided by 2 which is r[i], how can I get this in R?I wrote the following code but it is just save each iteration values,not the whole iterations.
r = rep(0, 10)
res = matrix(0, nrow=200, ncol=1)
for(j in 1:20){
for(i in 1:10){
x = rnorm(10, 0, 1)
r[i] = x/2
}
res = rbind(r)
}
as Roland said in a comment to your question writing two loops for this isn't a good practice. However, you can do it like this
res = rep(0, 200)
r = rep(0, 10)
for(j in 1:20){
for(i in 1:10){
x = rnorm(1, 0, 1)
r[i] = x/2
}
res[((j-1)*10+1):(j*10)] = r
}
As for your solution, there were some problems:
There is no need to define a matrix res = matrix(0, nrow=200, ncol=1) if you only need a vector
rnorm(10,0,1) returns a vector of 10 values so assigning it to r[i] (which takes only one value) isn't correct
rbind is used to connect two vectors/matrices/... by rows so using it with only one parameter doesn't really make a sense here

Resources