根据条件语句使用mutate()计算有序观测值

时间:2019-05-28 14:00:37

标签: r dplyr conditional-statements mutate

在尝试按另一个变量分组后(类似于other users),我试图计算特定行之间的增长率。

以下是我的数据示例:

squirrel_id    wt   age    trialdate 
   22639      9.7     0    2017-04-20
   22639      45.9   24    2017-05-14
   22639     130     53    2017-06-12 #caught 3x, 1 trial
   22640     10.3    0     2017-04-20
   22640     49.2    24    2017-05-14
   22640     121     52    2017-06-11
   22640     196     84    2017-07-13 #caught 4x, 2 trials
   23943     12.9     1    2018-04-27
   23943     57.2    26    2018-05-23 #caught 2x, 1 trial
   23760     150     73    2018-06-18
   23760     165     84    2018-06-29 #caught 2x, 2 trials

要以这种形式获取此数据,请确保首先使用arrange_by(squirrel_id)软件包library(dplyr)

我要做的是计算以下两者之间的增长率:

  1. 最后一次观察和倒数第二次观察除以经过的时间(last_wt-second_last_wt / last_age-second_last_age):[使用squirrel_id 22640:(196-121)/(84-52)],然后添加一个“ trial”一栏显示为“ 2”
  2. 倒数第二次观察和倒数第三次观察除以经过的时间(second_last_wt-third_last_wt / second_last_age-third_last_age):[使用squirrel_id 22640:(121-49.2)/(52-24)],然后添加一列称为“试验”的列,其内容为“ 1”

有一个问题:

  1. 如果一个squirrel_id的总观看次数为3次或更少(例如squirrel_id 22639和23943),则他们通常仅进行了1次试验,因此1增长率的计算。

  2. 但是,如果其中两个观察值的年龄大于40天(例如squirrel_id 23760),则他们进行了2次试验。

我希望有一个看起来像这样的最终数据集:

squirrel_id    wt   age    trialdate    g.rate     trial
   22639      9.7     0    2017-04-20   NA         NA
   22639      45.9   24    2017-05-14   NA         NA
   22639     130     53    2017-06-12   3.0        1     #caught 3x, 1 trial
   22640     10.3    0     2017-04-20   NA         NA
   22640     49.2    24    2017-05-14   NA         NA
   22640     121     52    2017-06-11   2.6         1
   22640     196     84    2017-07-13   2.3         2     #caught 4x, 2 trials
   23943     12.9     1    2018-04-27   NA         NA
   23943     57.2    26    2018-05-23   1.7         1     #caught 2x, 1 trial
   23760     150     73    2018-06-18    NA        1      
   23760     165     84    2018-06-29    1.4        2     #caught 2x, 2 trials

如果可能,我希望使用dplyr()解决方案。

2 个答案:

答案 0 :(得分:2)

这里是使用dplyr的一种方法,假设您的数据是如上所述的df ...

library(dplyr)
df %>% 
  arrange(squirrel_id, age) %>%                        #sort by id and age
  group_by(squirrel_id) %>%                            #group by id
  mutate(g.rate = c(NA, diff(wt) / diff(age)),         #calculate g.rate
         trial = row_number() - n() + 2                #counting up to 2 at end
                 - (n() <= 3)                          #-1 if 3 or fewer in group
                 + (n() <= 3 & sort(-age)[2] <= -40),  #+1 if also both age>40
         trial = ifelse(trial<1, NA, trial),           #set to NA if less than 1
         g.rate = ifelse(is.na(trial), NA, g.rate))    #set to NA if trial is NA

   squirrel_id    wt   age trialdate  g.rate trial
 1       22639   9.7     0 2017-04-20  NA       NA
 2       22639  45.9    24 2017-05-14  NA       NA
 3       22639 130      53 2017-06-12   2.9      1
 4       22640  10.3     0 2017-04-20  NA       NA
 5       22640  49.2    24 2017-05-14  NA       NA
 6       22640 121      52 2017-06-11   2.56     1
 7       22640 196      84 2017-07-13   2.34     2
 8       23760 150      73 2018-06-18  NA        1
 9       23760 165      84 2018-06-29   1.36     2
10       23943  12.9     1 2018-04-27  NA       NA
11       23943  57.2    26 2018-05-23   1.77     1

请注意,最后两个ID的顺序与数据的顺序不同。您只需在第一步中执行arrange(age)即可避免这种情况。

答案 1 :(得分:1)

这是使用tidyverse的另一种方法:

library(tidyverse)

df %>%
  arrange(squirrel_id, age) %>%
  group_by(squirrel_id) %>%
  mutate(trial = case_when(all(tail(age, 2) > 40) ~ c(rep(NA, n() - 2), 1, 2),
                           TRUE ~ c(rep(NA, n() - 1), 1)),
         g.rate = replace((wt -lag(wt)) / (age - lag(age)), 
                           1:(match(1, trial) - 1), NA)) %>%
  ungroup()
#> # A tibble: 11 x 6
#>    squirrel_id    wt   age trialdate  trial g.rate
#>          <dbl> <dbl> <dbl> <chr>      <dbl>  <dbl>
#>  1       22639   9.7     0 2017-04-20    NA  NA   
#>  2       22639  45.9    24 2017-05-14    NA  NA   
#>  3       22639 130      53 2017-06-12     1   2.9 
#>  4       22640  10.3     0 2017-04-20    NA  NA   
#>  5       22640  49.2    24 2017-05-14    NA  NA   
#>  6       22640 121      52 2017-06-11     1   2.56
#>  7       22640 196      84 2017-07-13     2   2.34
#>  8       23760 150      73 2018-06-18     1  NA   
#>  9       23760 165      84 2018-06-29     2   1.36
#> 10       23943  12.9     1 2018-04-27    NA  NA   
#> 11       23943  57.2    26 2018-05-23     1   1.77