My R code:
((x[1]-xm)^2)+((x[2]-xm)^2)+((x[3]-xm)^2)+((x[4]-xm)^2)+((x[5]-xm)^2)+((x[6]-xm)^2)
This computation would be much easier if i formulated the problem as a summation. How do I do that in r? Something like:
sum((x[i]-xm)^2) for i=1 to i=6?
x is a data frame.
Without reading all the responses in this thread, there is a really easy way to do summations in R.
Modify the following two lines as needed to accommodate a matrix or other type of vector:
i <- 0:5; sum(i^2)
Use i for your index when accessing a position in your vector/array.
Note that i can be any vector.
You need to use sum(), example below:
IndexStart <- 1
x <- seq(IndexStart, 6, 1)
xm <- 1
result1 <- ((x[1]-xm)^2)+((x[2]-xm)^2)+((x[3]-xm)^2)+((x[4]-xm)^2)+((x[5]-xm)^2)+((x[6]-xm)^2)
print(result1)
# [1] 55
result2 <- sum((x-xm)^2) # <- Solution
print(result2)
# [1] 55
Related
I am trying to create a matrix of coordinates(indexes) that I randomly pick one from using the sample function. I then use these to select a cell in another matrix. What is the best way to do this? The trouble is how to store these integers in the matrix so that they are easy to separate. Right now I have them stored as strings with a comma, that I then split. Someone suggested I use a pair, or a string, but I cannot seam to get these to work with a matrix. Thanks!
EDIT:What i currently have looks like this (changed a little to make sense out of context):
probs <- matrix(c(0,0,0.6,0,0,
0,0.7,1,0.7,0,
0.6,1,0,1,0.6,
0,0.7,1,0.7,0,
0,0,0.6,0,0),5,5)
cordsMat <- matrix("",5,5)
for (x in 1:5){
for (y in 1:5){
cordsMat[x,y] = paste(x,y,sep=",")
}
}
cords <- sample(cordsMat,1,,probs)
cordsVec <- unlist(strsplit(cords,split = ","))
cordX <- as.numeric(cordsVec[1])
cordY <- as.numeric(cordsVec[2])
otherMat[cordX,cordY]
It sort of works but i would also be interested for a better way, as this will get repeated a lot.
If you want to set the probabilities it can easily be done by providing it to sample
# creating the matrix
matrix(sample(rep(1:6, 15:20), 25), 5) -> other.mat
# set the probs vec
probs <- c(0,0,0.6,0,0,
0,0.7,1,0.7,0,
0.6,1,0,1,0.6,
0,0.7,1,0.7,0,
0,0,0.6,0,0)
# the coordinates matrix
mat <- as.matrix(expand.grid(1:nrow(other.mat),1:ncol(other.mat)))
# sampling a row randomly
sample(mat, 1, prob=probs) -> rand
# getting the value
other.mat[mat[rand,1], mat[rand,2]]
[1] 6
I have been trying to avoid for loops in R. However, I have had issues with using lapply with replicate in that the lists I obtain have ordering that are not sequential. For example, the following code:
lapply(1:5, function(x) replicate(100, rnorm(x), simplify = F))
creates 100 instances of each: rnorm(1), rnorm(2), ..., rnorm(5).
This is much faster than using a for loop. However, the resulting list indices I get are:
.........
[[5]][[98]]
[1] -0.87686000 -0.82373642 -0.05671333 -2.24652788 -1.43497760
[[5]][[99]]
[1] -1.6935926 0.4753606 0.1190997 0.1464246 0.8604974
[[5]][[100]]
[1] 0.68414921 0.32183115 1.23681540 -1.34076190 -0.08467215
while what I want is:
[[1]] -0.87686000
[[2]] -0.8237
......
[[500]] 1.236
Is there a way to modify the code above so that it order the list from 1 to 500? Thanks!
You can just call unlist() on the result, e.g.:
unlist(lapply(1:5, function(x) replicate(100, rnorm(x))))
Though note that you'll get an atomic vector of length 1500 -- since you're generating 1+2+3+4+5=15 random values 100 times.
That what you're aiming for?
If the goal is to get 500 total values, where the mean changes from 1 to 5 within each iteration, then you can just say:
unlist(lapply(1:5, function(x) replicate(100, rnorm(1, mean=x))))
You can see the upward trend with, e.g.:
values <- unlist(lapply(1:5, function(x) replicate(100, rnorm(1, mean=x))))
plot(seq_along(values), values)
I am trying to make a $n\times 4$ matrix by retrieving the n-th four elements in a given vector. Since I am new to R, don't know how to use loop functions properly.
My code is like
x<-runif(150,-2,2)
x1<-c(0,0,0,0,x)
for (i in 0:150)
{ai<-x1[1+i,4+i]
}
However, I got: Error in x1[1 + i, 4 + i] : incorrect number of dimensions.
I also want to combine these ai into a matrix, and each ai will be the i+1-th row of the matrix. Guess I should use the cbind function?
Any help will be appreciated. Thanks in advance.
You can do this directly with the matrix command:
x <- 1:36
xmat<-matrix(x,nr=9,byrow=TRUE)
May be this helps:
n <- length(x1)-1
res <- sapply((4:n)-3, function(i) x1[(i+3):i])
dim(res)
#[1] 4 150
I have an ODE model in Matlab for which I'm interested in performing some parameter sweeps.
I am trying to port the following code from Matlab to R
for i = 1:numel(sweep1)
initial_conditions(6)=sweep1(i);
for j = 1:numel(sweep2)
parameters(3)=sweep2(j);
[t,y] = ode23s(#(timespan, initial_conditions) MODEL(timespan, initial_conditions, parameters), timespan, initial_conditions);
results_cell{i,j}=[y(end,1),y(end,2)];
The 2 FOR statements above vary first 1 initial condition (i), then for each i vary a parameter (j) and run the solver. The output from the solver for each iteration of the loop is then collected in a cell 'results_cell'
This runs fine in Matlab but I need to port it to R. The loops are the same and the solver code is implemented using deSolve, however I am not sure how to collect the results from the solver at each iteration of the loop as R doesn't have cells like Matlab, and how to gather {i,j} from each loop along with the 2 ode outputs.
Ultimately I would like to plot a heat map of the ode solver output vs the values in each of the 2 parameter sweeps.
Thanks for any help.
Here what I would do: I run the ode23 once to get the structure of the solution.
sweep1 =2
sweep2 =3
library(pracma)
f <- function(t, x,i=1,j=0)
as.matrix(c(x[1] * ((i+j) - x[2]^2) -x[2], x[1]))
t0 <- 0
tf <- 20
x0 <- as.matrix(c(0, 0.25))
sol = ode23(f, t0, tf, x0,1,1)$y
res = tail(sol,1)
Then I use replicate to create the structure of the final output matrix. Using this trick avoid us to deal with pre-allocating arrays. replicate will do for us.
results_cell = replicate(sweep1,replicate(sweep2,res))
I just run my final simulation and assign each solution to results_cell
for (i in seq(sweep1))
for (j in seq(sweep2))
results_cell[,,j,i] = tail(ode23(f, t0, tf, x0,i,j)$y,1)
I'm assuming sweep1 and sweep2 are both vectors of numbers. What you can do is use expand.grid to make a data frame of the combinations of that, and then loop over the frame once with apply:
# sweep 1, sweep 2
sweep1 <- c(1, 2, 4)
sweep2 <- c(3, 5, 7)
# expand out the combinations
combinations <- expand.grid(sweep1=sweep1, sweep2=sweep2)
# apply over the data frame
results <- apply(combinations, 1, function(row) {
# set up the parameters from the row which has been passed in.
initial_conditions[6] <- row["sweep1"]
parameters[3] <- row["sweep2"]
# call ode23s
res <- ode23s(initial_conditons, parameters, function, whatever, ...)
# there should be a nicer way than calling nrow twice here, but R doesn't
# seem to have the nice 'end' keyword
# also, we copy in the row, so that's in the output.
c(row, one=res[nrow(res), 1], two=res[nrow(res), 2])
})
# because the apply has flipped rows to columns...
results <- as.data.frame(t(results))
results
# sweep1 sweep2 one two
# 1 1 3 ... ...
# 2 2 3 ... ...
# ...
The result of all this is a data frame of the input combinations and the output combinations. If you want more factors, add on a sweep3, but beware of the combinatorial complexity...
I'm trying to create a loop that creates a series of objects that contains a random sample, like this:
sample <- ceiling(runif(9, min=0, max=20))
(This is an example for a rounded uniform, but it can be replaced by a normal, poisson or whatever you want).
So, I built a loop for generate automatically various of those generators, with the objective of include them in a data frame. Then, the loop I designed was this:
N=50
dep=as.vector(N)
count=1
for (i in 1:N){
dep[count] <- ceiling(runif(9, min=0, max=20))
count=count+1
}
But it didn't work! For each dep[i] I have only a number, not a list of nine.
How I should do it? And if I want to include every dep[i] in a data frame?
Thanks so much, I hope you understand what i want.
It's because you've made dep a vector (these are 1D by default), but you're trying to store a 2-dimensional object in it.
You can dep off as NULL and rbind (row-bind) to it in the loop.Also, note that instead of using count in your loop you can just use i:
dep <- NULL
for (i in 1:N){
dep <- rbind(dep, ceiling(runif(9, min=0, max=20)))
}
# if you look at dep now it's a 2D matrix.
# We'll convert to data frame
dep <- as.data.frame(dep)
However, there's a simpler way to do this. You don't have to generate dep row-by-row, you can generate it up front, by making a vector containing 9*N of your rounded uniform distribution numbers:
dep <- ceiling(runif(9*N,min=0,max=20))
Now, dep is currently a vector of length 9*N. Let's make it into a Nx9 matrix:
dep <- matrix(dep,nrow=N)
Done!
So you can do all your code above in one line:
dep <- matrix( ceiling(runif(9*N,min=0,max=20)), nrow=N )
If you want you can call data.frame on dep (after it's been put into its 2D matrix form) to get a data frame.
As #mathematical.coffee explained. But also, it seems in your case for runif, you can use sample instead. And actually sample.int is more reliable. ...And about 3x faster than using runif here):
N <- 1000000
system.time( dep <- matrix(sample.int(20, 9*N, replace=TRUE), N) ) # 0.16 secs
range(dep) # 1 20
system.time( dep <- matrix(ceiling(runif(9*N, min=0, max=20)), N) ) # 0.45 secs
range(dep) # 1 20