使用 group_by 时重新排序 NA 的位置

Reorder position of NA's when using 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))])

关于如何做到这一点有什么想法吗?

您应该删除 mutate 语句中的 df$ 部分,否则您指的是完整的列,而不是每组的列。所以这应该可以正常工作:

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