【问题标题】:Calculations for ordered observations using mutate() based on conditional statements基于条件语句使用 mutate() 计算有序观察
【发布时间】:2019-10-14 02:00:46
【问题描述】:

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

这是我的数据示例:

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) 包。

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

  1. 最后一次观察和倒数第二次观察除以已经过去的时间 (last_wt-second_last_wt/last_age-second_last_age): [使用squirrel_id22640: (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_id23760),那么他们进行了 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() 解决方案。

【问题讨论】:

    标签: r conditional-statements dplyr


    【解决方案1】:

    这是一种方法,使用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) 来避免这种情况。

    【讨论】:

      【解决方案2】:

      这是使用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
      

      【讨论】:

        猜你喜欢
        • 2016-01-08
        • 1970-01-01
        • 1970-01-01
        • 2021-08-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-08-03
        相关资源
        最近更新 更多