我正在尝试将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
我找到了类似的解决方案here,但无法使其起作用:
df1 %>% arrange_(.dots = c("grp", "desc(myCol)"))
错误:找不到对象“ myCol”
感觉好像我缺少一些非常明显的想法吗?
最佳答案
我们可以将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