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



我想根据不同的列对数据帧中的行进行排序,但我不知道如何实现这一点。这里有一个例子需要澄清:

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 Y L
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

在这个例子中;A";通过增加";X〃;。具有";B";通过递减"来排序;X〃;并且具有"0"的值;C";通过增加";Y";。

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

谢谢!

您可以使用order使用的条件创建一个新向量。

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

我会编写一个函数来完成这项工作。使用order_pattern,您可以指定要订购的列,以及应该增加还是减少

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

一个选项是创建一个新列,并用与您的排序方案相对应的值填充它,按该列排序,然后删除该列(decorate-sort-uncorate:https://en.wikipedia.org/wiki/Schwartzian_transform)

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 

相关内容

  • 没有找到相关文章

最新更新