Использование «first» в mutate - PullRequest
0 голосов
/ 25 января 2019

Мой фрейм данных выглядит примерно как первые четыре столбца следующего:

   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

Я пытаюсь добавить пятый столбец «Соотношение», содержащий отношение значения каждой строки в секундах и первое не-NA значение ID-группы «Среднее». Как мне это сделать?

Я пробовал несколько вещей:

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 голосов
/ 25 января 2019

Попробуйте это:

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)]))
  ) 
0 голосов
/ 25 января 2019

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