Search code examples
rfor-looprate

How do I find the rate of weight loss of individual animals using a 'for loop'?


I'm trying to calculate how much water weight was lost by 13 frogs and toads (5 frogs, 8 toads) placed in front of a fan for a total of 45 minutes (don't worry! all toads and frogs are ok!).
I weighed each individual(g) after 9 minutes, so I have a total of 5 measurements. I want to know the rate of water lost of each at 9 minutes interval.
When I run a for loop, I only get a rate for the first measurement. How to get a rate for each 9 minute interval for all 13 animals?

This is what my code looks like:

for(i in 1: length(EWL)) { 
  for(j in 1:13) {
    ft <- EWL[which(EWL$Animal == as.character(j)), ]
    wr <- (ft[6, "Weight"] - ft[1, "Weight"]) / 45
    EWL$WR[EWL$Animal == as.character(j)] <- wr
  }
}

For toad 1, this code gave me -.06, which is repeated for all 5 measurements. Same thing for toad 2, I get -.08 for each interval. The math is correct for the first interval calculation, it's just repeated for all intervals.

My data looks like this:

> EWL
   Time Weight Posture Animal Size Species
1     0  204.4       3      1    L    toad
2     9  199.6       3      1    L    toad
3    18  197.6       4      1    L    toad
4    27  196.3       3      1    L    toad
5    36  194.5       4      1    L    toad
6    45  192.8       4      1    L    toad
7     0   30.7       2      2    S    toad
8     9   30.1       2      2    S    toad
9    18   29.4       3      2    S    toad
10   27   29.1       4      2    S    toad
11   36   28.8       5      2    S    toad
12   45   28.3       5      2    S    toad

dput:

structure(list(Time = c(0, 9, 18, 27, 36, 45, 0, 9, 18, 27, 36, 
45), Weight = c(204.4, 199.6, 197.6, 196.3, 194.5, 192.8, 30.7, 
30.1, 29.4, 29.1, 28.8, 28.3), Posture = c(3, 3, 4, 3, 4, 4, 
2, 2, 3, 4, 5, 5), Animal = c(1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 
2), Size = c("L", "L", "L", "L", "L", "L", "S", "S", "S", "S", 
"S", "S"), Species = c("toad", "toad", "toad", "toad", "toad", 
"toad", "toad", "toad", "toad", "toad", "toad", "toad")), class = "data.frame", row.names = c(NA, 
-12L))

Solution

  • Your code calculates weight loss rate wr per minute from a difference between the first measurement at time 0 and last measurement at time 45. This is a single number per animal. The last line then inputs that one number to all lines for the animal.

    To calculate wr per minute for all intervals in a for cycle, use:

    for(i in 1:13) { 
        ft <- EWL[which(EWL$Animal == as.character(i)), ]
        # difference between subsequent weight divided by interval length
        wr <- diff(ft[, "Weight"], lag = 1) / 9
        # first value is NA, because toads did not lose weight at time 0
        EWL$WR[EWL$Animal == as.character(i)] <- c(NA, wr)
    }
    
    print(EWL)
    #    Time Weight Posture Animal Size Species          WR
    # 1     0  204.4       3      1    L    toad          NA
    # 2     9  199.6       3      1    L    toad -0.53333333
    # 3    18  197.6       4      1    L    toad -0.22222222
    # 4    27  196.3       3      1    L    toad -0.14444444
    # 5    36  194.5       4      1    L    toad -0.20000000
    # 6    45  192.8       4      1    L    toad -0.18888889
    # 7     0   30.7       2      2    S    toad          NA
    # 8     9   30.1       2      2    S    toad -0.06666667
    # 9    18   29.4       3      2    S    toad -0.07777778
    # 10   27   29.1       4      2    S    toad -0.03333333
    # 11   36   28.8       5      2    S    toad -0.03333333
    # 12   45   28.3       5      2    S    toad -0.05555556
    

    However, note that a linear mixed model might be more suitable for the analysis of this data.

    # assumes different intercept for each animal
    fit <- lme4::lmer(Weight ~ Time + (1 | Animal), data = EWL)
    # assumes different slope for each animal
    fit <- lme4::lmer(Weight ~ Time + (Time | Animal), data = EWL)