Сортировка в R с помощью dplyr: Как отсортировать по категории в одном столбце на основе суммы категории в другом столбце? - PullRequest
3 голосов
/ 01 мая 2020

У меня есть пример кадра данных ниже. Мне нужно отсортировать его по типу, виду и BdFt. Приведенный ниже пример почти верен, однако я не хочу, чтобы виды сортировались в алфавитном порядке. Я хотел бы отсортировать виды на основе суммы каждого вида (в пределах каждого "типа") в порядке убывания. Так, например, в типе 4404 «DF» должен появляться первым. Я также хотел бы сохранить текущее количество наблюдений, поэтому я не хочу объединяться по группам видов. Может ли кто-нибудь помочь мне достичь этого, возможно, с помощью dplyr?

-Brandon

   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

Ответы [ 2 ]

3 голосов
/ 01 мая 2020

Вот один вариант с 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))),]

data

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))
2 голосов
/ 01 мая 2020

Альтернатива, хотя и не такая краткая, как ответ Акруна.

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(...).)

...