对另一列的每个级别内的数据框中的单个列重新排序

时间:2018-01-31 10:38:15

标签: r dataframe

这个问题的解决方案可能很容易,但我看不出来。这是我的示例数据框:

df <- data.frame(id=c(1,1,1,2,2,2), value=rep(1:3,2), level=rep(letters[1:3],2))
df[6,2] <- NA

以下是我想要创建的所需输出:

df$new_value <- c(3,2,1,NA,2,1)

因此,所有列的顺序都相同,而new_value列的value列顺序在id列的每个级别内都会相反。有任何想法吗?谢谢!

3 个答案:

答案 0 :(得分:5)

正如我理解你的问题一样,如果您只是想要在不进行排序的情况下撤销订单,那么您的数据是如何排序的巧合:

library(dplyr)
df %>% group_by(id) %>% mutate(new_value = rev(value)) %>% ungroup

# A tibble: 6 x 4
     id value  level new_value
  <dbl> <int> <fctr>     <int>
1     1     1      a         3
2     1     2      b         2
3     1     3      c         1
4     2     1      a        NA
5     2     2      b         2
6     2    NA      c         1

答案 1 :(得分:3)

稍微不同的方法,使用sort函数中的参数:

library(dplyr)
df %>% group_by(id) %>% 
mutate(value = sort(value, decreasing=TRUE, na.last=FALSE))

输出:

# A tibble: 6 x 3
# Groups: id [2]
     id value level 
  <dbl> <int> <fctr>
1  1.00     3 a     
2  1.00     2 b     
3  1.00     1 c     
4  2.00    NA a     
5  2.00     2 b     
6  2.00     1 c

希望这有帮助!

答案 2 :(得分:2)

我们可以对缺失值和列本身使用order

library(dplyr)
df %>% 
     group_by(id) %>%
     mutate(new_value = value[order(!is.na(value), -value)])
# A tibble: 6 x 4
# Groups: id [2]
#     id value level  new_value
#  <dbl> <int> <fctr>     <int>
#1  1.00     1 a              3
#2  1.00     2 b              2
#3  1.00     3 c              1
#4  2.00     1 a             NA
#5  2.00     2 b              2
#6  2.00    NA c              1

或使用arrange

中的dplyr
df %>% 
    arrange(id, !is.na(value), desc(value)) %>% 
    transmute(new_value = value) %>%
    bind_cols(df, .)

或使用base R并在na.last

中将FALSE选项指定为order
with(df, ave(value, id, FUN = function(x) x[order(-x, na.last = FALSE)]))
#[1]  3  2  1 NA  2  1