user2472273
user2472273

Reputation: 125

Two for loops in R

I want to simulate daily values from monthly values following the formula: V(d)=V(m)*(1+noise), noise is normally distributed with mean 0 and standard deviation 0.18)

I have monthly values in 12x1 matrix called wind.m and days in each month in another 12x1 matrix called day.I use two for loops:

for (i in (1:12)) {
  for (j in (1:12)){
    A<-wind.m[i,]*(1+rnorm(day[j,],0,0.18))
  }
  print(A)
}

the result of this code simulates 12 sets of 31 daily values, which is wrong (Feb has 28 days, April, June have 30 days etc) I'm not sure how to fix my codes.

the following is the data used:

> wind.m
      [,1]
 [1,] 2.78
 [2,] 2.93
 [3,] 3.09
 [4,] 3.11
 [5,] 3.44
 [6,] 3.44
 [7,] 3.71
 [8,] 3.86
 [9,] 4.05
[10,] 4.08
[11,] 4.22
[12,] 4.30
> day
      [,1]
 [1,]   31
 [2,]   28
 [3,]   31
 [4,]   30
 [5,]   31
 [6,]   30
 [7,]   31
 [8,]   31
 [9,]   30
[10,]   31
[11,]   30
[12,]   31

Upvotes: 2

Views: 1669

Answers (2)

Kikapp
Kikapp

Reputation: 2393

You could leave the loops out AND solve your problem AND learn a bit about R vectorization in three easy steps.

Setup:

wind.m <- c(2.78, 2.93, 3.09, 3.11, 3.44, 3.44, 
            3.71, 3.86, 4.05, 4.08, 4.22, 4.30)
day <- c(31, 28, 31, 30, 31, 30, 
         31, 31, 30, 31, 30, 31)

Then use rep to expand your monthly means into daily values for a year.

day_means <- rep(wind.m, times = day)

Then generate your simulated values.

A <- rnorm(length(day_means), mean = day_means , sd=0.18) 

A is your simulated data.

Upvotes: 2

dickoa
dickoa

Reputation: 18437

No need for nested loops. I think you can use mapply in this case.

set.seed(42)
df <- data.frame(month = month.abb,
                 numb_day = c(31, 28, 31, 30, 31, 30, 31,
                 31, 30, 31, 30 , 31),
                 wind_m = rnorm(12, mean = 20, sd = 5))

addNoise <- function(n, x) x * (1 + rnorm(n, 0, 0.18))

wind_d <- mapply(addNoise, df$numb_day, df$wind_m)
str(wind_d)
## List of 12
##  $ : num [1:31] 21.5 27.5 35.5 38.6 21.6 ...
##  $ : num [1:28] 21.7 11.3 15 16.2 12 ...
##  $ : num [1:31] 13.7 20.8 17.2 27.5 27.1 ...
##  $ : num [1:30] 26.3 14.2 20.2 23.1 17.1 ...
##  $ : num [1:31] 17.3 22.5 22 26.1 25.6 ...
##  $ : num [1:30] 20.8 12.8 13.1 15.5 18.3 ...
##  $ : num [1:31] 32.1 19.7 30.5 28 32.4 ...
##  $ : num [1:31] 19.5 19.5 20.1 21.6 19.1 ...
##  $ : num [1:30] 35.5 34.1 26.7 32.2 25.3 ...
##  $ : num [1:31] 22.7 19.5 15.8 21.7 24.3 ...
##  $ : num [1:30] 20.2 32.2 23.7 32.3 24.3 ...
##  $ : num [1:31] 41.2 31.1 28.4 35.7 28.7 ...

EDIT : Using the data of the OP

set.seed(123)
wind_d <- mapply(addNoise, day, wind.m)
## List of 12
##  $ : num [1:31] 2.5 2.66 3.56 2.82 2.84 ...
##  $ : num [1:28] 2.77 3.4 3.39 3.36 3.29 ...
##  $ : num [1:31] 3.21 3.3 2.81 2.9 2.52 ...
##  $ : num [1:30] 3.67 3.42 3.24 2.76 3.87 ...
##  $ : num [1:31] 3.51 2.85 3.14 3.28 4.58 ...
##  $ : num [1:30] 3.92 3.65 2.82 3.37 3.27 ...
##  $ : num [1:31] 4.55 3.48 3.13 3.55 3.58 ...
##  $ : num [1:31] 4.72 3.5 3.17 5.02 3.55 ...
##  $ : num [1:30] 3.22 3.92 5.44 3.98 3.06 ...
##  $ : num [1:31] 3.06 4.7 3.75 4.21 4.13 ...
##  $ : num [1:30] 3.89 4.47 2.69 4.38 5.16 ...
##  $ : num [1:31] 4.59 2.71 3.24 4.14 4.97 ...

Upvotes: 1

Related Questions