按降序排列多个列的 arrange_() 函数

15

我正在尝试使用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'

感觉好像我漏掉了一些很明显的东西,有什么想法吗?

2个回答

13

我们可以将字符串“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'的值。

更新

或者另一个选择是使用rlang中的parse_expr,并用!!进行评估。

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's post),将字符串转换为符号(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




 

是的,这些都是不错的替代方案,但希望有更优美的解决方案来避免粘贴。 - zx8754
1
@zx8754 我加了一个 interp 选项,但我认为使用 paste 更简洁。 - akrun
4
同意,粘贴似乎是一个可行的方法,“interp”使它看起来更糟(无冒犯之意)。 - zx8754
你介意也加上“quosures”方法吗?我无法让它正常工作。 - zx8754
1
@zx8754 我使用了rlang添加了一个选项。 - akrun

4
这可能会奏效: arrange(grp, across(c(x), desc))

dplyr 版本 1.0.5


这是最优雅和最新的解决方案。 - pietrodito

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接