使用 dplyr 在 R 中排序:如何根据另一列中的类别总和按一列中的类别排序?
Sorting in R with dplyr: How to sort by category in one column based on sum of category in another column?
我在下面有一个示例数据框。我需要按类型、物种和 BdFt 对它进行排序。下面的例子几乎是正确的,但我不希望物种按字母顺序排序。我想根据每个物种的总和(在每个 "type" 内)按降序对物种进行排序。因此,例如,在类型 4404 中,'DF' 应该首先出现。我也想保持当前的观察数量,所以我不想按物种组合并。任何人都可以帮助我实现这一点,也许可以使用 dplyr?
-布兰登
Type Species BdFt
4404 BB 164
4404 BB 55
4404 BM 831
4404 BM 419
4404 BM 242
4404 BM 20
4404 CH 565
4404 CH 206
4404 CH 88
4404 CO 1817
4404 CO 531
4404 CO 286
4404 CO 31
4404 DF 19740
4404 DF 5930
4404 DF 613
4404 DF 468
4404 DF 167
4404 GF 360
4404 GF 232
4404 GF 124
4410 BM 909
4410 CH 161
4410 DF 18756
4410 GF 3642
4410 RA 549
这里有一个选项 arrange
library(dplyr)
df2 <- df1 %>%
arrange(Type, desc(ave(BdFt, Species, Type, FUN = sum)))
df2
# Type Species BdFt
#1 4404 DF 19740
#2 4404 DF 5930
#3 4404 DF 613
#4 4404 DF 468
#5 4404 DF 167
#6 4404 CO 1817
#7 4404 CO 531
#8 4404 CO 286
#9 4404 CO 31
#10 4404 BM 831
#11 4404 BM 419
#12 4404 BM 242
#13 4404 BM 20
#14 4404 CH 565
#15 4404 CH 206
#16 4404 CH 88
#17 4404 GF 360
#18 4404 GF 232
#19 4404 GF 124
#20 4404 BB 164
#21 4404 BB 55
#22 4410 DF 18756
#23 4410 GF 3642
#24 4410 BM 909
#25 4410 RA 549
#26 4410 CH 161
或 order
来自 base R
df1[with(df1, order(Type, -ave(BdFt, Species, Type, FUN = sum))),]
数据
df1 <- structure(list(Type = c(4404L, 4404L, 4404L, 4404L, 4404L, 4404L,
4404L, 4404L, 4404L, 4404L, 4404L, 4404L, 4404L, 4404L, 4404L,
4404L, 4404L, 4404L, 4404L, 4404L, 4404L, 4410L, 4410L, 4410L,
4410L, 4410L), Species = c("BB", "BB", "BM", "BM", "BM", "BM",
"CH", "CH", "CH", "CO", "CO", "CO", "CO", "DF", "DF", "DF", "DF",
"DF", "GF", "GF", "GF", "BM", "CH", "DF", "GF", "RA"), BdFt = c(164L,
55L, 831L, 419L, 242L, 20L, 565L, 206L, 88L, 1817L, 531L, 286L,
31L, 19740L, 5930L, 613L, 468L, 167L, 360L, 232L, 124L, 909L,
161L, 18756L, 3642L, 549L)), class = "data.frame", row.names = c(NA,
-26L))
另一种选择,虽然不像 akrun 的回答那么简洁。
library(dplyr)
library(tidyr)
dat %>%
group_by(Type, Species) %>%
summarize(SumBdFt = sum(BdFt)) %>%
ungroup() %>%
full_join(dat, by = c("Type", "Species")) %>%
arrange(Type, desc(SumBdFt), BdFt) %>%
select(-SumBdFt)
# # A tibble: 26 x 3
# Type Species BdFt
# <int> <fct> <int>
# 1 4404 DF 167
# 2 4404 DF 468
# 3 4404 DF 613
# 4 4404 DF 5930
# 5 4404 DF 19740
# 6 4404 CO 31
# 7 4404 CO 286
# 8 4404 CO 531
# 9 4404 CO 1817
# 10 4404 BM 20
# # ... with 16 more rows
数据
dat <- read.table(header=TRUE, text="
Type Species BdFt
4404 BB 164
4404 BB 55
4404 BM 831
4404 BM 419
4404 BM 242
4404 BM 20
4404 CH 565
4404 CH 206
4404 CH 88
4404 CO 1817
4404 CO 531
4404 CO 286
4404 CO 31
4404 DF 19740
4404 DF 5930
4404 DF 613
4404 DF 468
4404 DF 167
4404 GF 360
4404 GF 232
4404 GF 124
4410 BM 909
4410 CH 161
4410 DF 18756
4410 GF 3642
4410 RA 549")
(知道 ave
与 group_by(...) %>% summarize(...)
的效果相同可能会提供信息。)
我在下面有一个示例数据框。我需要按类型、物种和 BdFt 对它进行排序。下面的例子几乎是正确的,但我不希望物种按字母顺序排序。我想根据每个物种的总和(在每个 "type" 内)按降序对物种进行排序。因此,例如,在类型 4404 中,'DF' 应该首先出现。我也想保持当前的观察数量,所以我不想按物种组合并。任何人都可以帮助我实现这一点,也许可以使用 dplyr?
-布兰登
Type Species BdFt
4404 BB 164
4404 BB 55
4404 BM 831
4404 BM 419
4404 BM 242
4404 BM 20
4404 CH 565
4404 CH 206
4404 CH 88
4404 CO 1817
4404 CO 531
4404 CO 286
4404 CO 31
4404 DF 19740
4404 DF 5930
4404 DF 613
4404 DF 468
4404 DF 167
4404 GF 360
4404 GF 232
4404 GF 124
4410 BM 909
4410 CH 161
4410 DF 18756
4410 GF 3642
4410 RA 549
这里有一个选项 arrange
library(dplyr)
df2 <- df1 %>%
arrange(Type, desc(ave(BdFt, Species, Type, FUN = sum)))
df2
# Type Species BdFt
#1 4404 DF 19740
#2 4404 DF 5930
#3 4404 DF 613
#4 4404 DF 468
#5 4404 DF 167
#6 4404 CO 1817
#7 4404 CO 531
#8 4404 CO 286
#9 4404 CO 31
#10 4404 BM 831
#11 4404 BM 419
#12 4404 BM 242
#13 4404 BM 20
#14 4404 CH 565
#15 4404 CH 206
#16 4404 CH 88
#17 4404 GF 360
#18 4404 GF 232
#19 4404 GF 124
#20 4404 BB 164
#21 4404 BB 55
#22 4410 DF 18756
#23 4410 GF 3642
#24 4410 BM 909
#25 4410 RA 549
#26 4410 CH 161
或 order
来自 base R
df1[with(df1, order(Type, -ave(BdFt, Species, Type, FUN = sum))),]
数据
df1 <- structure(list(Type = c(4404L, 4404L, 4404L, 4404L, 4404L, 4404L,
4404L, 4404L, 4404L, 4404L, 4404L, 4404L, 4404L, 4404L, 4404L,
4404L, 4404L, 4404L, 4404L, 4404L, 4404L, 4410L, 4410L, 4410L,
4410L, 4410L), Species = c("BB", "BB", "BM", "BM", "BM", "BM",
"CH", "CH", "CH", "CO", "CO", "CO", "CO", "DF", "DF", "DF", "DF",
"DF", "GF", "GF", "GF", "BM", "CH", "DF", "GF", "RA"), BdFt = c(164L,
55L, 831L, 419L, 242L, 20L, 565L, 206L, 88L, 1817L, 531L, 286L,
31L, 19740L, 5930L, 613L, 468L, 167L, 360L, 232L, 124L, 909L,
161L, 18756L, 3642L, 549L)), class = "data.frame", row.names = c(NA,
-26L))
另一种选择,虽然不像 akrun 的回答那么简洁。
library(dplyr)
library(tidyr)
dat %>%
group_by(Type, Species) %>%
summarize(SumBdFt = sum(BdFt)) %>%
ungroup() %>%
full_join(dat, by = c("Type", "Species")) %>%
arrange(Type, desc(SumBdFt), BdFt) %>%
select(-SumBdFt)
# # A tibble: 26 x 3
# Type Species BdFt
# <int> <fct> <int>
# 1 4404 DF 167
# 2 4404 DF 468
# 3 4404 DF 613
# 4 4404 DF 5930
# 5 4404 DF 19740
# 6 4404 CO 31
# 7 4404 CO 286
# 8 4404 CO 531
# 9 4404 CO 1817
# 10 4404 BM 20
# # ... with 16 more rows
数据
dat <- read.table(header=TRUE, text="
Type Species BdFt
4404 BB 164
4404 BB 55
4404 BM 831
4404 BM 419
4404 BM 242
4404 BM 20
4404 CH 565
4404 CH 206
4404 CH 88
4404 CO 1817
4404 CO 531
4404 CO 286
4404 CO 31
4404 DF 19740
4404 DF 5930
4404 DF 613
4404 DF 468
4404 DF 167
4404 GF 360
4404 GF 232
4404 GF 124
4410 BM 909
4410 CH 161
4410 DF 18756
4410 GF 3642
4410 RA 549")
(知道 ave
与 group_by(...) %>% summarize(...)
的效果相同可能会提供信息。)