R 如何根据不同的列和值在数据框内进行部分排序?

R 如何根据不同的列和值在数据框内进行部分排序?,r,dataframe,partial-ordering,R,Dataframe,Partial Ordering,我想根据不同的列对数据帧中的行进行排序,但我不知道如何实现这一点。这里举一个例子来说明: x <- data.frame(X=c(10:1), Y=c(6,6,3,6,3,3,9,9,9,2), L=c("A","B","C","C","A","B","C","A","B","C")) x

我想根据不同的列对数据帧中的行进行排序,但我不知道如何实现这一点。这里举一个例子来说明:

x <- data.frame(X=c(10:1), Y=c(6,6,3,6,3,3,9,9,9,2), L=c("A","B","C","C","A","B","C","A","B","C"))
x 
    X Y L 
1  10 6 A
2   9 6 B
3   8 3 C
4   7 6 C
5   6 3 A
6   5 3 B
7   4 9 C
8   3 9 A
9   2 9 B
10  1 2 C
在本例中,通过增加“X”对“A”值进行排序。具有“B”的值通过减小“X”进行排序,具有“C”的值通过增大“Y”进行排序

这可以通过
order()
%>%arrange
来完成吗? (数据帧较大)


谢谢

您可以使用订单使用的条件创建一个新向量

y <- x$X
i <- x$L == "B"
y[i] <- y[i] * -1
i <- x$L == "C"
y[i] <- x$Y[i]
x[order(x$L, y),]
#    X Y L
#8   3 9 A
#5   6 3 A
#1  10 6 A
#2   9 6 B
#6   5 3 B
#9   2 9 B
#10  1 2 C
#3   8 3 C
#4   7 6 C
#7   4 9 C

y我将编写一个函数来为您完成这项工作。使用
order\u模式
可以指定要对哪些列进行排序,以及是增加还是减少

order_pattern <- list(A = c("X", "inc"), B = c("X", "dec"), C = c("Y", "inc"))
 
order_partly <- function(dat, ord_pat){
  result <- dat[0,]
  for (pattern_col in names(ord_pat)){
    order_col <- ord_pat[[pattern_col]][1]
    decreasing <- if (ord_pat[[pattern_col]][2] == "dec") T else F
    partial_dat <- dat[dat$L == pattern_col,]
    ord <- order(partial_dat[order_col], decreasing = decreasing)
    result <- rbind(result, partial_dat[ord, ])
  }
  result
}

order_partly(x, order_pattern)

    X Y L
8   3 9 A
5   6 3 A
1  10 6 A
2   9 6 B
6   5 3 B
9   2 9 B
10  1 2 C
3   8 3 C
4   7 6 C
7   4 9 C

order\u pattern一个选项是创建一个新列,并用对应于您的订购方案的值填充它,按该列排序,然后删除该列(修饰-排序-取消修饰:)

库(tidyverse)
x%
组别(1)%>%
变异(shwartz=ifelse(L==“A”,X,
如果是(L==“B”,1/X,
如果是(L==“C”,Y,
“错误”))%%>%
排列(L,shwartz)%>%
选择(-shwartz)%>%
解组()
#一个tibble:10x3
#X Y L
#     
#1 3 9 A
#2 6 3 A
#3 10 6 A
#4 9 6 B
#5 3 B
#629b
#7 1 2 C
#83C
#9 7 6 C
#10 4 9 C

我们还可以使用以下解决方案:

library(dplyr)
library(purrr)

df %>%
  group_split(L) %>%
  map_dfr(~ if(.x$L[1] == "A") {
    .x %>% arrange(.x$X)
  } else if(.x$L[1] == "B") {
    .x %>% arrange(desc(.x$X))
  } else {
    .x %>% arrange(.x$Y)
  })

# A tibble: 10 x 3
       X     Y L    
   <int> <dbl> <chr>
 1     3     9 A    
 2     6     3 A    
 3    10     6 A    
 4     9     6 B    
 5     5     3 B    
 6     2     9 B    
 7     1     2 C    
 8     8     3 C    
 9     7     6 C    
10     4     9 C 
库(dplyr)
图书馆(purrr)
df%>%
组分割(L)%>%
映射(如果(.x$L[1]=“A”){
.x%>%排列(.x$x)
}否则,如果(.x$L[1]=“B”){
.x%>%排列(描述(.x$x))
}否则{
.x%>%排列(.x$Y)
})
#一个tibble:10x3
X Y L
1 3 9 A
2 6 3 A
3 10 6 A
4 9 6 B
5 3 B
629b
7 1 2 C
83C
9 7 6 C
10 4 9 C

这是一种很好的方法;如果数据帧较大,则此方法将是最快的
library(tidyverse)
x <- data.frame(X=c(10:1), Y=c(6,6,3,6,3,3,9,9,9,2), L=c("A","B","C","C","A","B","C","A","B","C"))
x %>%
  group_by(L) %>%
  mutate(shwartz = ifelse(L == "A", X,
                          ifelse(L == "B", 1 / X,
                                 ifelse(L == "C", Y,
                                        "error")))) %>% 
  arrange(L, shwartz) %>% 
  select(-shwartz) %>% 
  ungroup()
# A tibble: 10 x 3
#       X     Y L    
#   <int> <dbl> <chr>
# 1     3     9 A    
# 2     6     3 A    
# 3    10     6 A    
# 4     9     6 B    
# 5     5     3 B    
# 6     2     9 B    
# 7     1     2 C    
# 8     8     3 C    
# 9     7     6 C    
#10     4     9 C   
library(dplyr)
library(purrr)

df %>%
  group_split(L) %>%
  map_dfr(~ if(.x$L[1] == "A") {
    .x %>% arrange(.x$X)
  } else if(.x$L[1] == "B") {
    .x %>% arrange(desc(.x$X))
  } else {
    .x %>% arrange(.x$Y)
  })

# A tibble: 10 x 3
       X     Y L    
   <int> <dbl> <chr>
 1     3     9 A    
 2     6     3 A    
 3    10     6 A    
 4     9     6 B    
 5     5     3 B    
 6     2     9 B    
 7     1     2 C    
 8     8     3 C    
 9     7     6 C    
10     4     9 C