Arr_() несколько столбцов с убывающим порядком

Я пытаюсь использовать arrange_() со строковым вводом и в одном из столбцов в порядке убывания.

library(dplyr) # R version 3.3.0 (2016-05-03) , dplyr_0.4.3 
# data
set.seed(1)
df1 <- data.frame(grp = factor(c(1,2,1,2,1)),
                  x = round(runif(5,1,10), 2))

#   grp    x
# 1   1 3.39
# 2   2 4.35
# 3   1 6.16
# 4   2 9.17
# 5   1 2.82

Ниже я хочу достичь:

df1 %>% arrange(grp, -x)
df1 %>% arrange(grp, desc(x))
#   grp    x
# 1   1 6.16
# 2   1 3.39
# 3   1 2.82
# 4   2 9.17
# 5   2 4.35

В моем случае второй столбец представляет собой строку:

#dynamic string
myCol <- "x"

#failed attempts
df1 %>% arrange_("grp", desc(myCol))

Ошибка: неправильный размер (1), ожидающий: 5

df1 %>% arrange_("grp", "desc(myCol)")

Ошибка: объект 'myCol' не найден

df1 %>% arrange_(c("grp", "desc(myCol)"))
#wrong output
#   grp    x
# 1   1 3.39
# 2   1 6.16
# 3   1 2.82
# 4   2 4.35
# 5   2 9.17

Я нашел подобное решение здесь, но не смог заставить его работать:

df1 %>% arrange_(.dots = c("grp", "desc(myCol)"))

Ошибка: объект 'myCol' не найден

Похоже, что мне не хватает чего-то очень очевидного, идей?

Ответы

Ответ 1

Мы можем paste 'desc' как строку для оценки.

myCol1 <- paste0("desc(", "x)")
df1 %>% 
     arrange_(.dots = c("grp", myCol1))
#  grp    x
#1   1 6.16
#2   1 3.39
#3   1 2.82
#4   2 9.17
#5   2 4.35

Или с "myCol"

df1 %>% 
      arrange_(.dots = c("grp", paste0("desc(", myCol, ")")))

Или использовать lazyeval

library(lazyeval)
df1 %>%
     arrange_(.dots = c("grp", interp(~ desc(n1), n1 = as.name(myCol))))
#  grp    x
#1   1 6.16
#2   1 3.39
#3   1 2.82
#4   2 9.17
#5   2 4.35

При использовании "desc(myCol)" это одна строка, и значение myCol не оценивается.

Обновить

Или другой вариант - parse_expr (от rlang) и оцените с помощью !!

df1 %>%
    arrange(grp, !! rlang::parse_expr(myCol1))
#grp    x
#1   1 6.16
#2   1 3.39
#3   1 2.82
#4   2 9.17
#5   2 4.35

Или используя оригинальную строку в посте OP. Преобразуйте строку в символ (sym), оцените (!!) и расположите ее в порядке убывания (desc).

myCol <- "x"
df1 %>% 
    arrange(grp, desc(!! rlang::sym(myCol)))
# grp    x
#1   1 6.16
#2   1 3.39
#3   1 2.82
#4   2 9.17
#5   2 4.35

Ответ 2

очень поздний ответ на это, но для упорядочения есть функцияrange_(), в которую вы можете передать список символов для сортировки.