0

I am hoping someone may be able to help me to calculate the age (in days) of each animal in my data set?

My data look like the below and describe individual animals captured and measured through time. example$frab.num is a factor variable that provides a unique animal identifier, example$date is a date variable (class "Date") that describes the date that the animal was captured and example$wt is the weight of the animal at capture in grams.

In total my data frame includes >3800 individual animals that have been captured between 1996 and 2020. Some animals are caught up to 30 times during their life, but on average animals only live for 1-3 years and may be captured only 3 or 4 times during their life.

> example
   frab.num       date   wt
1       001 1996-10-22 1600
2       002 1996-10-22 1450
3       003 1996-10-22 1800
4       004 1996-10-22 1450
5       005 1996-10-22 1700
6       006 1996-10-22 1750
7       007 1996-10-22 1800
8       008 1996-10-22 1350
9       009 1996-10-22 1750
10      010 1996-10-22 1100
11      011 1996-10-22 1000
12      012 1996-10-22 1400
13      013 1996-10-22 1750
14      014 1996-10-22 1400
15      015 1996-10-22 1200
16      016 1996-10-22  700
17      017 1996-10-22 1000
18      018 1996-10-22  450
19      019 1996-10-22  300
20      020 1996-10-22 1100

If an animal is first caught before 1500 grams weight then we can calculate their age in days because we know that they grow approximately 10 grams per day on average. This will obtain an age at first capture for each individual animal. We can then calculate the age of each animal at subsequent capture dates by adding age at first capture date and the time difference in days between the first and subsequent capture dates. We cannot calculate the age of animals that are >1500 grams when first captured.

EDIT: a large example dataset can be accessed here

EDIT 2: an example of what the output would look like is below. Note that this is only a small example so no re-captures are included. NA values in age represent instances where the animal was greater than 1500 grams when first captured and hence age could not be calculated.

> example
   frab.num       date   wt age
1       001 1996-10-22 1600 NA
2       002 1996-10-22 1450 145
3       003 1996-10-22 1800 NA
4       004 1996-10-22 1450 145
5       005 1996-10-22 1700 NA
6       006 1996-10-22 1750 NA
7       007 1996-10-22 1800 NA
8       008 1996-10-22 1350 135
9       009 1996-10-22 1750 NA
10      010 1996-10-22 1100 110
11      011 1996-10-22 1000 100
12      012 1996-10-22 1400 140
13      013 1996-10-22 1750 NA
14      014 1996-10-22 1400 140
15      015 1996-10-22 1200 120
16      016 1996-10-22  700  70
17      017 1996-10-22 1000 100
18      018 1996-10-22  450  45
19      019 1996-10-22  300  30
20      020 1996-10-22 1100 110

Thank you in advance

Pat Taggart
  • 321
  • 1
  • 9
  • If we are calculating the age at capture, we need the birthdate as well. The calculation for age in R has also been already answered in previous posts--e.g., https://stackoverflow.com/questions/3611314/calculate-ages-in-r/25450756#25450756. – LC-datascientist Nov 17 '20 at 04:51
  • Thanks @Ronak Shah and @LC-datascientist. I made a few edits to post, hopefully they make sense. I do not have animal birth date, instead we know that they grow about 10 grams per day up until they reach 1500 grams weight. Therefore, if we capture them before 1500 grams weight we can essentially estimate their birth date by doing ```example$date - (example$wt/10)``` - if they are over 1500 grams when first captured then we can't estimate age at all. – Pat Taggart Nov 17 '20 at 05:02

2 Answers2

2

Try this

library(tidyverse)

df <- read.csv("example2.csv")
df$date <- as.Date(df$date, format = "%d-%m-%Y")

df %>% group_by(frab.num) %>%
  mutate(capture_no = row_number()) %>%
  mutate(age = ifelse(capture_no == 1 & wt > 1500, NA, 
                      ifelse(capture_no == 1, wt/10, 
                             first(wt)/10 + 
                        difftime(date, first(date), units = 'days')))) %>%
  ungroup()

# A tibble: 150 x 5
   frab.num date          wt capture_no   age
      <int> <date>     <int>      <int> <dbl>
 1        1 1996-10-22  1600          1    NA
 2        2 1996-10-22  1450          1   145
 3        3 1996-10-22  1800          1    NA
 4        4 1996-10-22  1450          1   145
 5        5 1996-10-22  1700          1    NA
 6        6 1996-10-22  1750          1    NA
 7        7 1996-10-22  1800          1    NA
 8        8 1996-10-22  1350          1   135
 9        9 1996-10-22  1750          1    NA
10       10 1996-10-22  1100          1   110
# ... with 140 more rows

Check for frab.num = 273

df %>% group_by(frab.num) %>%
  mutate(capture_no = row_number()) %>%
  mutate(age = ifelse(capture_no == 1 & wt > 1500, NA, 
                      ifelse(capture_no == 1, wt/10, 
                             first(wt)/10 + 
                        difftime(date, first(date), units = 'days')))) %>%
  ungroup() %>% filter(frab.num == 273)
                    
# A tibble: 3 x 5
  frab.num date          wt capture_no   age
     <int> <date>     <int>      <int> <dbl>
1      273 1997-04-02  1460          1   146
2      273 1997-06-12     0          2   217
3      273 1997-08-15     0          3   281
AnilGoyal
  • 25,297
  • 4
  • 27
  • 45
1

We could use dplyr and case_when (in the event you want to add multiple conditions).

CODE

library(dplyr)
example %>% 
  mutate(
    age = case_when(
    wt < 1500 ~ wt/10
    )

OUTPUT

   frab.num       date   wt age
1         1 1996-10-22 1600  NA
2         2 1996-10-22 1450 145
3         3 1996-10-22 1800  NA
4         4 1996-10-22 1450 145
5         5 1996-10-22 1700  NA
6         6 1996-10-22 1750  NA
7         7 1996-10-22 1800  NA
8         8 1996-10-22 1350 135
9         9 1996-10-22 1750  NA
10       10 1996-10-22 1100 110
11       11 1996-10-22 1000 100
12       12 1996-10-22 1400 140
13       13 1996-10-22 1750  NA
14       14 1996-10-22 1400 140
15       15 1996-10-22 1200 120
16       16 1996-10-22  700  70
17       17 1996-10-22 1000 100
18       18 1996-10-22  450  45
19       19 1996-10-22  300  30
20       20 1996-10-22 1100 110
Russ Thomas
  • 938
  • 4
  • 13
  • 23
  • 1
    Thanks @Russ Thomas. This is similar to what I had tried; it works for calculating the age of the animals at first capture, but does not calculate the age of the animals correctly at subsequent captures. The age of animals at first capture, if they are less than 1500 grams, is simply ```example$wt/10```. The age of animals at subsequent captures is ```example$wt/10``` for the first capture plus ```example$date``` for current capture minus ```example$date``` of first capture. However, if animals are greater than 1500 grams at first capture we cannot calculate age at any captures. – Pat Taggart Nov 17 '20 at 05:13