【问题标题】:arrange_() multiple columns with descending order以降序排列多个列
【发布时间】:2016-10-29 08:54:25
【问题描述】:

我正在尝试将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”

感觉我遗漏了一些非常明显的想法?

【问题讨论】:

    标签: r dplyr


    【解决方案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
    
    
    
    
     
    

    【讨论】:

    • 是的,这些都是不错的选择,希望有更漂亮的解决方案避免粘贴。
    • @zx8754 我添加了一个带有interp 的选项,但我认为带有paste 的选项很紧凑
    • 同意,粘贴似乎是一种方法,interp 让它看起来更糟(没有冒犯)。
    • 你介意添加“quosures”方法吗?无法让它工作。
    • @zx8754 我用rlang添加了一个选项
    【解决方案2】:

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

    dplyr版本1.0.5

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-09-02
      • 1970-01-01
      • 2014-07-06
      • 2012-06-25
      • 2010-11-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多