如何在R中向上移动每个组内的值

ami*_*s55 6 r dataset

我需要将有效值转移到每个 .dataframe 的顶部id。这是一个示例数据集:

df <- data.frame(id = c(1,1,1,2,2,2,3,3,3,3),
                 itemid = c(1,2,3,1,2,3,1,2,3,4),
                 values = c(1,NA,0,NA,NA,0,1,NA,0,NA))
    
df
   id itemid values
1   1      1      1
2   1      2     NA
3   1      3      0
4   2      1     NA
5   2      2     NA
6   2      3      0
7   3      1      1
8   3      2     NA
9   3      3      0
10  3      4     NA
Run Code Online (Sandbox Code Playgroud)

不包括 id 列,当values列中缺少值时,我想将每个值移动到顶部对齐id

我怎样才能获得下面这个所需的数据集?

df1
   id itemid values
1   1      1      1
2   1      2      0
3   1      3     NA
4   2      1      0
5   2      2     NA
6   2      3     NA
7   3      1      1
8   3      2      0
9   3      3     NA
10  3      4     NA
Run Code Online (Sandbox Code Playgroud)

Ben*_*Ben 8

使用tidyverse你可以arrange通过是否values丢失(这会将它们放在底部)。

library(tidyverse)

df %>%
  arrange(id, is.na(values))
Run Code Online (Sandbox Code Playgroud)

输出

      id itemid values
   <dbl>  <dbl>  <dbl>
 1     1      1      1
 2     1      3      0
 3     1      2     NA
 4     2      3      0
 5     2      1     NA
 6     2      2     NA
 7     3      1      1
 8     3      3      0
 9     3      2     NA
10     3      4     NA
Run Code Online (Sandbox Code Playgroud)

或者,如果您希望为 和其他列保留相同的顺序itemid,您可以使用mutate来专门对感兴趣的列进行排序(例如values)。其他答案提供了很好的解决方案,例如@Santiago 和@ThomasIsCoding。如果您有多个感兴趣的列要移动NA到每组的底部,您还可以尝试:

df %>%
  group_by(id) %>%
  mutate(across(.cols = values, ~values[order(is.na(.))]))
Run Code Online (Sandbox Code Playgroud)

其中 .cols 参数将包含要独立转换和重新排序的列。

输出

      id itemid values
   <dbl>  <dbl>  <dbl>
 1     1      1      1
 2     1      2      0
 3     1      3     NA
 4     2      1      0
 5     2      2     NA
 6     2      3     NA
 7     3      1      1
 8     3      2      0
 9     3      3     NA
10     3      4     NA
Run Code Online (Sandbox Code Playgroud)