Возьмите n самых больших и самых низких значений с Tidyverse - PullRequest
1 голос
/ 29 марта 2020

Я хочу получить k наиболее вероятных и отрицательных значений для данного кадра данных без необходимости хранить их оба отдельно. В настоящее время я делаю что-то вроде следующего для k = 2:

df %>%
arrange(desc(n)) %>%
top_n(2)

df %>%
arrange(desc(n)) %>%
top_n(-2))

Но я хочу знать, есть ли более простой способ выполнить это без необходимости их сохранения, а затем bind_rows. Я полагаю, что так, потому что это действительно удобно для выполнения некоторых geom_bars.

. Предположим, я использую любой тиббл, например что-то вроде:

df <- tibble(x = 1:10, n = 1:10)

И я хочу получить значения 1,2,9,10

Ответы [ 4 ]

1 голос
/ 29 марта 2020

Для положительных / отрицательных значений я наткнулся на это решение

df %>%
  group_by(n < 0) %>%
  top_n(2, abs(n)) %>%
  ungroup()
1 голос
/ 29 марта 2020

Другой вариант:

library(dplyr)

df %>%
  slice(which(rank(n) %in% 1:2), which(rank(desc(n)) %in% 1:2))

Выход:

# A tibble: 4 x 2
      x     n
  <int> <int>
1     1     1
2     2     2
3     9     9
4    10    10
1 голос
/ 29 марта 2020

Мы можем использовать slice после arrange ing через 'n'. Здесь мы вызываем arrange только один раз

library(dplyr)
top_n_rows <- 2
df %>% 
    arrange(n) %>%
    slice(sort(c(seq_len(top_n_rows),  n() - seq_len(top_n_rows) + 1)))
# A tibble: 4 x 2
#      x     n
#  <int> <int>
#1     1     1
#2     2     2
#3     9     9
#4    10    10

. Или другой вариант: row_number()

df %>%
   arrange(n) %>%
   slice(c(head(row_number(), top_n_rows), tail(row_number(), top_n_rows)))

Если мы просто поднаборим первые n и последние n строк без учета каких-либо столбцов в порядке

rbind(head(df, top_n_rows), tail(df, top_n_rows))

или с row.names

df[c(head(row.names(df), top_n_rows), tail(row.names(df), top_n_rows)),]
0 голосов
/ 29 марта 2020

Мы можем предварительно рассчитать строки, которые мы хотим выбрать

no_rows <- 2
num <- c(1:no_rows, (nrow(df) - no_rows + 1):nrow(df))

, а затем мы можем использовать slice

library(dplyr)
df %>% slice(num)

#      x     n
#  <int> <int>
#1     1     1
#2     2     2
#3     9     9
#4    10    10

Или filter

df %>% filter(row_number() %in% num)

Очевидно, что это также работает с прямым поднабором:

df[num, ]

Кроме того, при использовании top_n нам не нужно arrange данные, мы можем напрямую использовать их

bind_rows(df %>% top_n(no_rows, n), df %>% top_n(-no_rows, n)) %>% arrange_all()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...