Можно ли использовать tidyr `fill ()` с if_else () в R? - PullRequest
3 голосов
/ 28 октября 2019
library(tidyverse)
df <- tibble(col1 = c("a", "a", "b", "b", "c", "c"),
             col2 = c(2, NA, 5, NA, 7, NA))
#> # A tibble: 6 x 2
#>   col1   col2
#>   <chr> <dbl>
#> 1 a         2
#> 2 a        NA
#> 3 b         5
#> 4 b        NA
#> 5 c         7
#> 6 c        NA

Давайте начнем с кадра данных выше. Я хочу заполнить col2, если значение col1 не равно a. Решение будет выглядеть так:

#> # A tibble: 6 x 2
#>   col1   col2  col3
#>   <chr> <dbl> <dbl>
#> 1 a         2     2
#> 2 a        NA    NA
#> 3 b         5     5
#> 4 b        NA     5
#> 5 c         7     7
#> 6 c        NA     7

Моя попытка ниже не работает. Как заставить tidyr::fill() работать в этом if_else() контексте?

df %>% mutate(col3 = if_else(col1 != "a", fill(col2), col2))
#> Error in UseMethod("fill_") : no applicable method for 'fill_' 
#> applied to an object of class "c('double', 'numeric')"

Ответы [ 2 ]

2 голосов
/ 28 октября 2019

Я не думаю, что это поведение поддерживается функцией. Вместо этого вы можете сделать:

df %>%
 filter(col1 == "a") %>%
 bind_rows(df %>%
            filter(col1 != "a") %>%
            fill(col2))

  col1   col2
  <chr> <dbl>
1 a         2
2 a        NA
3 b         5
4 b         5
5 c         7
6 c         7

Или, если вам действительно нужно col3, тогда вы можете использовать na.locf() из zoo:

df %>%
 mutate(col3 = ifelse(col1 != "a", na.locf(col2), col2))

  col1   col2  col3
  <chr> <dbl> <dbl>
1 a         2     2
2 a        NA    NA
3 b         5     5
4 b        NA     5
5 c         7     7
6 c        NA     7
0 голосов
/ 28 октября 2019

В любом случае не легко пользоваться приборкой. Вы просто должны сначала заполнить, а затем положить обратно NA

df <- df %>% mutate(col3=df %>% fill(col2) %>% pull(col2))
df$col3[df$col1=="a" & is.na(df$col2)] <- NA

Я думаю, что пример не такой четкий.

Что произойдет, если обе записи col2 для b равны NA? Тогда то, что предложил @tmfmnk, дало бы решение, отличное от указанного выше

...