arrange_()具有降序的多个列

时间:2016-06-27 11:04:19

标签: r dplyr

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

在我的情况下,第二列是一个字符串:

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

错误:大小不正确(1),期待:5

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
  

错误:未找到对象'myCol'

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

我找到了类似的解决方案here,但无法使其正常工作:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        div {
            background: red;
            margin: 5px;
        }

        table {
            border: 2px solid black;
        }

        td {
            padding: 10px;
            border: 1px solid lightgrey;
        }

    </style>

    <script>

        function createTable() {
            var a;

            a = document.getElementById('tb1').value;

            if (a == "") {
                alert("Please enter some numeric value");
            } else {
                var rows = "<th>Item Name</th><th>Quantity</th><th>QuantityType</th><th>Amount</th>";
                for (var i = 0; i < a; i++) {
                let tr = document.createElement("tr");
                tr.innerHTML = "<td><input type='text' name='" + "name".concat(i+1) + "'></td><td><input type='text' name='" + "quantity".concat(i+1) + "'></td><td><input type='text' name='" + "qtype".concat(i+1) + "'></td><td id='amt'><input type='text' id='sum' onkeyup='myfunction(this.value);' name='" + "total".concat(i+1) + "'></td>";
                document.getElementById("table").appendChild(tr);
                }                
            }
        }
    </script>
</head>
<body>
<input type="text" id="tb1"/>
<button type="button" onclick='createTable()'>Click Me!</button>
<table id="table" class="order-table table"  name="table1" required>
</table>
</body>
</html>
  

错误:未找到对象'myCol'

感觉我错过了一些非常明显的想法吗?

2 个答案:

答案 0 :(得分:11)

我们可以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

答案 1 :(得分:0)

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

dplyr 版本 1.0.5