【问题标题】:Order a data frame programmatically using a character vector of column names使用列名的字符向量以编程方式对数据框进行排序
【发布时间】:2017-05-10 15:46:32
【问题描述】:

我正在尝试在多列上排序数据框。并且列名通过变量传递,即字符向量。

df <- data.frame(var1 = c("b","a","b","a"), var2 = c("l","l","k","k"),
                 var3 = c("t","w","x","t"))

  var1 var2 var3
1    b    l    t
2    a    l    w
3    b    k    x
4    a    k    t

使用变量对一列进行排序

sortvar <- "var1"
df[order(df[ , sortvar]),]

  var1 var2 var3
2    a    l    w
4    a    k    t
1    b    l    t
3    b    k    x

现在,如果我想按两列排序,上面的解决方案不起作用。

sortvar <- c("var1", "var2")
df[order(df[, sortvar]), ] #does not work

我可以用列名手动排序:

df[with(df, order(var1, var2)),]

  var1 var2 var3
4    a    k    t
2    a    l    w
3    b    k    x
1    b    l    t

但是,如何使用具有列名的变量在多列上动态排序数据框?我知道plyrdplyr arrange 函数,但我想在这里使用base R。

【问题讨论】:

    标签: r dataframe sorting


    【解决方案1】:

    order 需要多个排序变量作为单独的参数,这在您的情况下很不幸,但建议使用直接解决方案:使用 do.call

    df[do.call(order, df[, sortvar]), ]
    

    如果您不熟悉 do.call:它以编程方式构造和执行调用。以下两个语句是等价的:

    fun(arg1, arg2, …)
    do.call(fun, list(arg1, arg2, …))
    

    【讨论】:

    • 类似变体:with(mtcars, do.call(order, mget(sortvar)))
    • 是否可以按降序排列变量之一?
    • @rmf 是的。如果它是一个数字变量,只需取反即可。如果不是数字,可以使用函数xtfrm从中生成数字顺序,然后取反that。但是,如果您仍然想按多个变量排序,并且只有其中一些是降序的,那就更费力了。
    • 没错。我想使用多个变量,其中一些是递减的。
    【解决方案2】:

    这有点尴尬,但您可以使用do.call() 将每一列作为不同的参数传递给order

    dat[do.call("order", dat[,cols, drop=FALSE]), ]
    

    我添加了drop=FALSE 以防万一length(cols)==1 索引data.frame 将返回向量而不是列表。您可以将其包装在一个函数中以使其更易于使用

    order_by_cols <- function(data, cols=1) {
      data[do.call("order", data[, cols, drop=FALSE]), ]
    }
    
    order_by_cols(dat, cols)
    

    如果您可以考虑的话,使用 dplyr 会更容易一些

    library(dplyr)
    dat %>% arrange(across(all_of(cols)))
    dat %>% arrange_at(cols)  # though this method has been superseded by the above line
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-06-02
      • 2015-02-08
      • 1970-01-01
      • 2016-09-30
      • 2021-03-18
      • 2013-06-02
      • 2018-06-25
      相关资源
      最近更新 更多