ima
ima

Reputation: 1

Why is my function to calculate Annualized Rate of Change returning NAs in R?

I have the following dataframe which has a long-running data. My goal is to calculated annualised rate of changes in what I call an 'aroc' function below. However, upon application of a function I get the aroc values as NA's. I have tried and tried and decided to submit myself to your help. As you know, for the first time point the aroc must be 0. In this case that first time point is year 1990. The code does paste the zero as required but does not calculate the arocs. I need your help. Please!

df <- data.frame (year_id = c(1990, 1990, 1991, 1991, 1992, 1992, 1993, 1993, 1994, 1994, 1995,   1995, 1996, 1996, 1997, 1997, 1998, 1998, 1999, 1999, 2000, 2000, 2001, 2001, 2002, 2002, 2003, 2003, 2004, 2004, 2005, 2005, 2006, 2006, 2007, 2007, 2008, 2008, 2009, 2009, 2010, 2010, 2011, 2011, 2012, 2012, 2013, 2013, 2014, 2014, 2015, 2015, 2016, 2016, 2017, 2017, 2018, 2018, 2019, 2019, 2020, 2020, 2021, 2021, 1990, 1990, 1991, 1991, 1992, 1992, 1993, 1993, 1994, 1994, 1995, 1995, 1996, 1996, 1997, 1997, 1998, 1998, 1999, 1999, 2000, 2000, 2001, 2001, 2002, 2002),
              sex = c("male",   "female", "male",   "female", "male",   "female", "male",   "female", "male",   "female", "male",   "female", "male",   "female", "male",   "female", "male",   "female", "male",   "female", "male",   "female", "male",   "female", "male",   "female", "male",   "female", "male",   "female", "male"  , "female", "male",   "female", "male",   "female", "male",   "female", "male",   "female", "male",   "female", "male",   "female", "male",   "female", "male",   "female", "male",   "female", "male",   "female", "male",   "female", "male",   "female", "male",   "female", "male",   "female", "male",   "female", "male",   "female", "male",   "female", "male",   "female", "male",   "female", "male",   "female", "male",   "female", "male",   "female", "male",   "female", "male"  , "female", "male"  , "female", "male"  , "female", "male",   "female", "male",   "female", "male",   "female"),
              loc  = c("C", "C", "C", "C",  "C", "C", "C", "C", "C", "C", "C", "C", "C", "C",  "C", "C", "C", "C",  "C", "C",  "C", "C", "C",   "C","C", "C", "C", "C",  "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C",   "C", "C", "C", "C", "C", "C", "C","C", "C", "C", "C",    "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C",   "C",   "C", "D", "D", "D" ,"D", "D", "D", "D", "D", "D", "D", "D", "D", "D", "D", "D", "D", "D", "D", "D", "D", "D", "D", "D", "D", "D", "D"),
                reg1 = c( "SOAEAO","SOAEAO","SOAEAO", "SOAEAO","SOAEAO","SOAEAO","SOAEAO","SOAEAO","SOAEAO","SOAEAO","SOAEAO","SOAEAO","SOAEAO","SOAEAO", "SOAEAO","SOAEAO","SOAEAO","SOAEAO","SOAEAO","SOAEAO","SOAEAO","SOAEAO", "SOAEAO","SOAEAO","SOAEAO","SOAEAO","SOAEAO","SOAEAO","SOAEAO","SOAEAO", "SOAEAO","SOAEAO","SOAEAO","SOAEAO","SOAEAO","SOAEAO","SOAEAO","SOAEAO", "SOAEAO","SOAEAO","SOAEAO","SOAEAO","SOAEAO","SOAEAO","SOAEAO","SOAEAO", "SOAEAO","SOAEAO","SOAEAO","SOAEAO","SOAEAO","SOAEAO","SOAEAO","SOAEAO", "SOAEAO","SOAEAO","SOAEAO","SOAEAO","SOAEAO","SOAEAO","SOAEAO","SOAEAO", "SOAEAO","SOAEAO","SOAEAO","SOAEAO","SOAEAO","SOAEAO","SOAEAO","SOAEAO", "SOAEAO","SOAEAO","SOAEAO","SOAEAO","SOAEAO","SOAEAO","SOAEAO","SOAEAO", "SOAEAO","SOAEAO","SOAEAO","SOAEAO","SOAEAO","SOAEAO","SOAEAO","SOAEAO", "SOAEAO","SOAEAO","SOAEAO","SOAEAO"), reg2 = c("EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA","EA"), val = c(0.000043700, 0.000019600, 0.000049300, 0.000022900, 0.000058200 ,0.000027000, 0.000068200, 0.000031700, 0.000080100, 0.000037800, 0.000093800, 0.000044800,0.000107661, 0.000051300, 0.000123680, 0.000058200, 0.000143318, 0.000066600, 0.000167694, 0.000076700, 0.000198397, 0.000089100, 0.000235314, 0.000103256,0.000277176, 0.000118437, 0.000321671, 0.000133436, 0.000368679, 0.000148275, 0.000411686, 0.000160694, 0.000437294, 0.000165787, 0.000456603, 0.000169191, 0.000473239, 0.000172542, 0.000475592, 0.000169768 ,0.000480068, 0.000168260, 0.000480103, 0.000166006, 0.000470809, 0.000159872, 0.000473221, 0.000159643, 0.000483188, 0.000161755, 0.000486762, 0.000162135, 0.000485582, 0.000160320, 0.000479532, 0.000157872, 0.000473521, 0.000154745, 0.000465836, 0.000150780, 0.000440927, 0.000141668, 0.000414025, 0.000131982, 0.000008850, 0.000002930, 0.000011700, 0.000004080, 0.000016800, 0.000006140, 0.000024500, 0.000009350, 0.000036500, 0.000014500, 0.000052200, 0.000021300, 0.000069400, 0.000029000, 0.000089700, 0.000038200, 0.000114664, 0.000049800, 0.000144987, 0.000063900, 0.000181219, 0.000080900, 0.000222981, 0.000100655, 0.000269623, 0.000122767) )   

Here is the function I created to calculate the annualised rate of change

#function

aroc <- function(x, t, mean = FALSE){
    t <- order(t)
    res <- numeric(length(x)-1)
    for(i in 1:(length(x)-1)){
      res[i] <- log((x[i+1]/x[i]))/(t[i+1]-t[i])
    }
    if(mean == TRUE){
    res <- mean(res)}
    return(aroc = res)
}

Here I am applying the function.

#calculations
df %>%
  select(year_id,loc,sex,val, reg1, reg2) %>%
  group_by(year_id,loc,sex) %>%
  mutate(
    aroc_pop = ifelse(
      as.numeric(year_id != 1990),
      aroc(val, as.numeric(year_id)),
      0
    )
  ) %>% 
  data.frame()

Here is the output with NAs on the new column 'aroc_pop'. How do I get the right values in the new column?

#output
year_id loc    sex         val   reg1 reg2 aroc_pop1     1990   C   male 0.000043700 SOAEAO   EA        02     1990   C female 0.000019600 SOAEAO   EA        03     1991   C   male 0.000049300 SOAEAO   EA       NA4     1991   C female 0.000022900 SOAEAO   EA       NA5     1992   C   male 0.000058200 SOAEAO   EA       NA6     1992   C female 0.000027000 SOAEAO   EA       NA7     1993   C   male 0.000068200 SOAEAO   EA       NA8     1993   C female 0.000031700 SOAEAO   EA       NA9     1994   C   male 0.000080100 SOAEAO   EA       NA10    1994   C female 0.000037800 SOAEAO   EA       NA11    1995   C   male 0.000093800 SOAEAO   EA       NA12    1995   C female 0.000044800 SOAEAO   EA       NA13    1996   C   male 0.000107661 SOAEAO   EA       NA14    1996   C female 0.000051300 SOAEAO   EA       NA15    1997   C   male 0.000123680 SOAEAO   EA       NA16    1997   C female 0.000058200 SOAEAO   EA       NA17    1998   C   male 0.000143318 SOAEAO   EA       NA18    1998   C female 0.000066600 SOAEAO   EA       NA19    1999   C   male 0.000167694 SOAEAO   EA       NA20    1999   C female 0.000076700 SOAEAO   EA       NA21    2000   C   male 0.000198397 SOAEAO   EA       NA22    2000   C female 0.000089100 SOAEAO   EA       NA23    2001   C   male 0.000235314 SOAEAO   EA       NA24    2001   C female 0.000103256 SOAEAO   EA       NA25    2002   C   male 0.000277176 SOAEAO   EA       NA26    2002   C female 0.000118437 SOAEAO   EA       NA27    2003   C   male 0.000321671 SOAEAO   EA       NA28    2003   C female 0.000133436 SOAEAO   EA       NA29    2004   C   male 0.000368679 SOAEAO   EA       NA30    2004   C female 0.000148275 SOAEAO   EA       NA31    2005   C   male 0.000411686 SOAEAO   EA       NA32    2005   C female 0.000160694 SOAEAO   EA       NA33    2006   C   male 0.000437294 SOAEAO   EA       NA34    2006   C female 0.000165787 SOAEAO   EA       NA35    2007   C   male 0.000456603 SOAEAO   EA       NA36    2007   C female 0.000169191 SOAEAO   EA       NA37    2008   C   male 0.000473239 SOAEAO   EA       NA38    2008   C female 0.000172542 SOAEAO   EA       NA39    2009   C   male 0.000475592 SOAEAO   EA       NA40    2009   C female 0.000169768 SOAEAO   EA       NA41    2010   C   male 0.000480068 SOAEAO   EA       NA42    2010   C female 0.000168260 SOAEAO   EA       NA43    2011   C   male 0.000480103 SOAEAO   EA       NA44    2011   C female 0.000166006 SOAEAO   EA       NA45    2012   C   male 0.000470809 SOAEAO   EA       NA46    2012   C female 0.000159872 SOAEAO   EA       NA47    2013   C   male 0.000473221 SOAEAO   EA       NA48    2013   C female 0.000159643 SOAEAO   EA       NA49    2014   C   male 0.000483188 SOAEAO   EA       NA50    2014   C female 0.000161755 SOAEAO   EA       NA51    2015   C   male 0.000486762 SOAEAO   EA       NA52    2015   C female 0.000162135 SOAEAO   EA       NA53    2016   C   male 0.000485582 SOAEAO   EA       NA54    2016   C female 0.000160320 SOAEAO   EA       NA55    2017   C   male 0.000479532 SOAEAO   EA       NA56    2017   C female 0.000157872 SOAEAO   EA       NA57    2018   C   male 0.000473521 SOAEAO   EA       NA58    2018   C female 0.000154745 SOAEAO   EA       NA59    2019   C   male 0.000465836 SOAEAO   EA       NA60    2019   C female 0.000150780 SOAEAO   EA       NA61    2020   C   male 0.000440927 SOAEAO   EA       NA62    2020   C female 0.000141668 SOAEAO   EA       NA63    2021   C   male 0.000414025 SOAEAO   EA       NA64    2021   C female 0.000131982 SOAEAO   EA       NA65    1990   D   male 0.000008850 SOAEAO   EA        066    1990   D female 0.000002930 SOAEAO   EA        067    1991   D   male 0.000011700 SOAEAO   EA       NA68    1991   D female 0.000004080 SOAEAO   EA       NA69    1992   D   male 0.000016800 SOAEAO   EA       NA70    1992   D female 0.000006140 SOAEAO   EA       NA71    1993   D   male 0.000024500 SOAEAO   EA       NA72    1993   D female 0.000009350 SOAEAO   EA       NA73    1994   D   male 0.000036500 SOAEAO   EA       NA74    1994   D female 0.000014500 SOAEAO   EA       NA75    1995   D   male 0.000052200 SOAEAO   EA       NA76    1995   D female 0.000021300 SOAEAO   EA       NA77    1996   D   male 0.000069400 SOAEAO   EA       NA78    1996   D female 0.000029000 SOAEAO   EA       NA79    1997   D   male 0.000089700 SOAEAO   EA       NA80    1997   D female 0.000038200 SOAEAO   EA       NA81    1998   D   male 0.000114664 SOAEAO   EA       NA82    1998   D female 0.000049800 SOAEAO   EA       NA83    1999   D   male 0.000144987 SOAEAO   EA       NA84    1999   D female 0.000063900 SOAEAO   EA       NA85    2000   D   male 0.000181219 SOAEAO   EA       NA86    2000   D female 0.000080900 SOAEAO   EA       NA87    2001   D   male 0.000222981 SOAEAO   EA       NA88    2001   D female 0.000100655 SOAEAO   EA       NA89    2002   D   male 0.000269623 SOAEAO   EA       NA90    2002   D female 0.000122767 SOAEAO   EA       NA

As detailed above, I wrote the aroc function and was expecting it would calculate the aroc_pop values. In addition, upon applying the aroc function on the population of females as follows:

aroc(df[df$sex == 'female', ]$val,as.numeric(df[df$sex == 'female', ]$year_id))%>% data.frame()

I get the correct values of aroc_pop for females in this case as follows:

1   4.862730e-03
2  -5.312902e-03
3   5.014994e-03
4  -5.677175e-03
5   5.309345e-03
6  -4.370407e-03
7   3.943581e-03
8  -4.349007e-03
9   4.412410e-03
10 -4.834117e-03
11  4.607875e-03
12 -4.424833e-03
13  3.726275e-03
14 -3.401506e-03
15  2.513540e-03
16 -1.006513e-03
17  6.351382e-04
18 -6.326591e-04
19 -5.064964e-04
20  2.878193e-04
21 -4.214522e-04
22  1.214530e-03
23 -4.479446e-05
24 -4.239604e-04
25  7.332740e-05
26  3.631453e-04
27 -1.538724e-02
28 -2.000598e-02
29 -2.595678e-02
30 -6.233553e-02
31 -7.082074e-02
32 -3.807663e+00
33  3.310946e-01
34  4.087278e-01
35  4.205516e-01
36  4.387723e-01
37  3.845584e-01
38  3.085888e-01
39  2.755397e-01
40  2.651795e-01
41  2.493044e-01
42  2.358945e-01
43  2.184850e-01
44  1.985894e-01

I could change 'females' to 'males' and still calculate these values. But it is not possible in the entire dataset because of NAs

Upvotes: 0

Views: 60

Answers (1)

PBulls
PBulls

Reputation: 1731

The formatting makes this difficult to follow, but I'm quite sure this is the answer: your group_by(year_id, loc, sex) results in n=1 observations per group. If you pipe this into your aroc function, which is written as if it expects vectors of at least length 2, the following happens (example for first observation in your dataset):

x <- 4.37e-05
x[2]
> NA

You'll either have to remove grouping variable(s) or add more records in the groups you have. You didn't explain what this function is supposed to do but based on it working across time I don't think you should be grouping by year_id.

Upvotes: 1

Related Questions