Изменение порядка расположения NA при использовании group_by

Я хотел бы изменить порядок расположения NA в столбце, внутри каждого уровня другой категориальной переменной. Например, с этим фреймом данных:

df <- data.frame(fact=c(1,1,1,2,2,2), id=rep(1:6), value=c(NA,44,23,NA,NA,76))

Я хотел бы изменить новый столбец, как:

df$newvar <= c(44,23,NA,76,NA,NA)

Я бы подумал, что следующее будет работать, но это не так:

dfb <- df %>% group_by(fact) %>% mutate(newvar = df$value[order(is.na(df$value))])

Любые идеи о том, как я могу это сделать?

4 ответа

Решение

Вы должны удалить df$ участвовать в выражении mutate, иначе вы ссылаетесь на полный столбец, а не на столбец для группы. Так что это должно работать нормально:

df %>% group_by(fact) %>% mutate(newvar = value[order(is.na(value))])

Выход:

# A tibble: 6 x 4
# Groups: fact [2]
   fact    id value newvar
  <dbl> <int> <dbl>  <dbl>
1  1.00     1  NA     44.0
2  1.00     2  44.0   23.0
3  1.00     3  23.0   NA  
4  2.00     4  NA     76.0
5  2.00     5  NA     NA  
6  2.00     6  76.0   NA  

Вам даже не нужно использовать dplyr Вы можете сделать это с базой R:

df$newvar <- ave(df$value, df$fact, FUN = function(x) x[order(-x)])

df
#  fact id value newvar
#1    1  1    NA     44
#2    1  2    44     23
#3    1  3    23     NA
#4    2  4    NA     76
#5    2  5    NA     NA
#6    2  6    76     NA

Другая идея заключается в использовании lead() функция сдвига вперед по количеству NA в каждой группе. т.е.

library(dplyr)

df %>% 
 group_by(fact) %>% 
 mutate(new = lead(value, sum(is.na(value))))

который дает

# A tibble: 6 x 4
# Groups:   fact [2]
   fact    id value   new
  <dbl> <int> <dbl> <dbl>
1  1.00     1  NA    44.0
2  1.00     2  44.0  23.0
3  1.00     3  23.0  NA  
4  2.00     4  NA    76.0
5  2.00     5  NA    NA  
6  2.00     6  76.0  NA  

ПРИМЕЧАНИЕ. Это будет работать только в том случае, если ваши NA находятся наверху, а они вам нужны внизу.

Еще одно предложение, используя arrange чтобы соответствовать глаголам dplyr:

df %>%
  mutate(newvar = 
    arrange(df, fact, is.na(value), id) %>% pull(value)
  )
Другие вопросы по тегам