Using apply functions in R to run function element by element over matrices
Asked Answered
I

3

5

I want to calculate growing degree days with several bases, using minimum daily temp, and maximum daily temp. I would like to do this without a for loop if possible to minimize my code.

bases <- c(40,45,50)
tmin <- runif(10,30,70)
tmax <- runif(10,55,95)

I want to find the number of growing degree days for each base for each of the ten days I have fake temperature data for. There should be 10 output values for each of the 3 bases.
I've tried mapply as follows:

gdd_func <- function(tmin,tmax,bases){
   (tmin + tmax)/2 - bases}

test <- mapply(gdd_func,tmin,tmax,bases)

This produces an incorrect output where I honestly don't know what it's doing. I want the output to be equal to running the above function 3 different times with the different bases. Each output would have 10 gdd values corresponding to the differing bases. How would I do this using an apply function of some kind? Or do I need something more?

Ida answered 6/10 at 21:17 Comment(0)
A
3

I think you should encapsulate tmin and tmax within a list, e.g.,

> mapply(gdd_func, list(tmin), list(tmax), bases)
           [,1]      [,2]      [,3]
 [1,] 19.119648 14.119648  9.119648
 [2,]  6.119249  1.119249 -3.880751
 [3,] 19.523350 14.523350  9.523350
 [4,] 13.023240  8.023240  3.023240
 [5,] 31.083015 26.083015 21.083015
 [6,] 32.281061 27.281061 22.281061
 [7,] 18.062584 13.062584  8.062584
 [8,] 18.047198 13.047198  8.047198
 [9,] 21.518514 16.518514 11.518514
[10,] 28.440563 23.440563 18.440563
Aegean answered 6/10 at 21:34 Comment(0)
S
4

Just for fun and even if this question already got a good answer, a loop/*apply free alternative, exploiting recycling:

gdd_func(tmin, tmax, rep(bases, each=length(tmin))) |> 
matrix(ncol = length(bases))

The above produces the same output as the @ThomasIsCoding's answer.

Scurf answered 7/10 at 7:58 Comment(0)
A
3

I think you should encapsulate tmin and tmax within a list, e.g.,

> mapply(gdd_func, list(tmin), list(tmax), bases)
           [,1]      [,2]      [,3]
 [1,] 19.119648 14.119648  9.119648
 [2,]  6.119249  1.119249 -3.880751
 [3,] 19.523350 14.523350  9.523350
 [4,] 13.023240  8.023240  3.023240
 [5,] 31.083015 26.083015 21.083015
 [6,] 32.281061 27.281061 22.281061
 [7,] 18.062584 13.062584  8.062584
 [8,] 18.047198 13.047198  8.047198
 [9,] 21.518514 16.518514 11.518514
[10,] 28.440563 23.440563 18.440563
Aegean answered 6/10 at 21:34 Comment(0)
C
2

outer is probably the best option here.

outer((tmin + tmax)/2, bases, "-")
#>           [,1]      [,2]      [,3]
#>  [1,] 13.70856  8.708559  3.708559
#>  [2,] 17.66631 12.666310  7.666310
#>  [3,] 21.00194 16.001937 11.001937
#>  [4,] 14.82080  9.820800  4.820800
#>  [5,] 21.35614 16.356138 11.356138
#>  [6,] 33.96390 28.963897 23.963897
#>  [7,] 28.37265 23.372649 18.372649
#>  [8,] 30.85054 25.850542 20.850542
#>  [9,] 32.30424 27.304244 22.304244
#> [10,] 40.03540 35.035405 30.035405
Carchemish answered 7/10 at 11:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.