Расчеты для упорядоченных наблюдений с использованием mutate () на основе условных операторов - PullRequest
3 голосов
/ 28 мая 2019

Я пытаюсь вычислить темпы роста между конкретными строками после группировки по другой переменной (аналогично 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)], а затем добавьте столбец с именем «Испытание» с надписью «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. НО, если 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 ]

2 голосов
/ 28 мая 2019

Вот один из способов сделать это, используя 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

Обратите внимание, что последние два идентификатора находятся в другом порядкечем ваши данные.Вы можете избежать этого, просто набрав arrange(age) на первом шаге.

1 голос
/ 29 мая 2019

Вот еще один подход, использующий 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...