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