在变异中使用“第一”

时间:2019-01-25 08:44:32

标签: r dplyr

我的数据框看起来类似于以下的前四列:

   ID             Obs    Seconds     Mean               Ratio
   <chr>        <dbl>         <dbl>   <dbl>             <dbl>
 1 1815522          1          1     NA                 1/10.6
 2 1815522          2         26     NA                 26/10.6       
 3 1815522          3          4.68  10.6               4.68/10.6
 4 1815522          4          0     10.2               0/10.6  
 5 1815522          5          1.5    2.06              1.5/10.6
 6 1815522          6          2.22   1.24              2.22/10.6
 7 1815676          1         12     NA                 12/9.67
 8 1815676          2          6     NA                 6/9.67    
 9 1815676          3         11      9.67              11/9.67 
10 1815676          4          1      6                 1/9.67 
11 1815676          5         30     14                 30/9.67 
12 1815676          6         29     20                 29/9.67
13 1815676          7         23     27.3               23/9.67
14 1815676          8         51     34.3               51/9.67

我试图添加第五列“比率”,其中包含每一行的秒数比值和ID组的第一个非NA平均值值之比。我该怎么办?

我尝试了几件事:

temp %>% 
  group_by(ID) %>% 
  mutate(Ratio = case_when(all(is.na(Mean)) ~ NA_real_, 
                                   !all(is.na(Mean)) ~ Seconds/(first(Mean[!is.na(Mean)]))))

这给了我以下错误:

Error in mutate_impl(.data, dots) : 
  Column `Ratio` must be length 2 (the group size) or one, not 0

我也尝试过

temp %>% 
  group_by(ID) %>% 
  mutate(Ratio = ifelse(!all(is.na(Mean)), Seconds/(first(Mean[!is.na(Mean)])), NA_real_))

但是在这种情况下,它将创建一个看起来像这样的列:

               Ratio
               <dbl>
 1            0.0947
 2            0.0947
 3            0.0947
 4            0.0947
 5            0.0947
 6            0.0947
 7            1.24  
 8            1.24  
 9            1.24  
10            1.24  
11            1.24  
12            1.24  
13            1.24  
14            1.24  

我真的不知道还能尝试什么。请帮忙! :)

2 个答案:

答案 0 :(得分:2)

一个想法是将fill.direction = 'up'一起使用,因为您对first值感兴趣,以填充NA,并简单地除以第一个值。无需case_when捕获所有NA,因为默认情况下它将给出NA作为答案,即

library(tidyverse)

df %>% 
 group_by(ID) %>% 
 fill(Mean, .direction = 'up') %>% 
 mutate(ratio = Seconds / first(Mean))

给出,

# A tibble: 14 x 5
# Groups:   ID [2]
        ID   Obs Seconds  Mean  ratio
     <int> <int>   <dbl> <dbl>  <dbl>
 1 1815522     1    1    10.6  0.0943
 2 1815522     2   26    10.6  2.45  
 3 1815522     3    4.68 10.6  0.442 
 4 1815522     4    0    10.2  0     
 5 1815522     5    1.5   2.06 0.142 
 6 1815522     6    2.22  1.24 0.209 
 7 1815676     1   12     9.67 1.24  
 8 1815676     2    6     9.67 0.620 
 9 1815676     3   11     9.67 1.14  
10 1815676     4    1     6    0.103 
11 1815676     5   30    14    3.10  
12 1815676     6   29    20    3.00  
13 1815676     7   23    27.3  2.38  
14 1815676     8   51    34.3  5.27

答案 1 :(得分:0)

尝试一下:

library(tidyverse)

 df %>%
  group_by(ID) %>%
  mutate(
    isNA = mean(is.na(Mean)),
    Ratio = if_else(isNA == 1, NA_real_, Seconds / first(Mean[!is.na(Mean)]))
  )