r - упорядочить значения в столбце на основе уникальных значений в другом столбце в группе - PullRequest
4 голосов
/ 10 октября 2019

Я пытаюсь изменить порядок столбцов в кадре данных в порядке убывания или возрастания на основе уникальных значений другого столбца в том же кадре данных в группах.

Для демонстрации этого ниже приведен пример ву которого датафрейм имеет три столбца. Цель состоит в том, чтобы сгруппировать по столбцу gr и упорядочить столбец a на основе уникального значения столбца b. Так, например, если в пределах gr=1 уникальное значение столбца b равно T, тогда я бы хотел столбец a в порядке возрастания, а если не в порядке убывания. Пример ниже

# sample dataset
df <-  data.frame(
    a = c(1,3,2,4),
    b = c(T,T,F,F),
    gr = c(1,1,2,2)
  )

# split dataset according to a grouping column
df <- df %>% split(df$gr)

# ordering function
f1 <- function(dt) {
  if (unique(dt$b) == T) {
    arrange(dt, a)
  } else {
    arrange(dt, -a)
  }
}

Требуемый набор данных должен выглядеть следующим образом:

# order within groups based on variable b
df %>% purrr::map_df(f1) 

Можно ли это сделать без использования списков или tidyr::nest? Использование простых dplyr::group_by и dplyr::arrange должно быть возможным и является наилучшим желаемым ответом.

Ответы [ 2 ]

3 голосов
/ 10 октября 2019

Вот способ.

library(dplyr)

f2 <- function(dt) {
  2*as.integer(df$b) - 1
}

df %>% arrange(gr, a*f2())

Если вы принимаете перестановку столбца gr, удалите его из arrange.

df %>% arrange(a*f2())

Редактировать.

Проще?

f2 <- function(x) 2*x - 1

df %>% arrange(gr, a*f2(b))
2 голосов
/ 10 октября 2019

Вот один вариант с arrange без каких-либо действий split

library(dplyr)
df %>%
   arrange(gr, c(1, -1)[gr] * a)
#  a     b gr
#1 1  TRUE  1
#2 3  TRUE  1
#3 4 FALSE  2
#4 2 FALSE  2

или, если необходимо, с 'b'

df %>% 
   arrange(gr, c(-1, 1)[(b + 1)] * a)
#  a     b gr
#1 1  TRUE  1
#2 3  TRUE  1
#3 4 FALSE  2
#4 2 FALSE  2

Здесь мы делаемиспользование numeric 'гр'. Если это не numeric, создайте индекс группировки с помощью match и используйте его для изменения значений 'a'

df %>%
   arrange(gr, c(1, -1)[match(gr, unique(gr))] * a)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...