【问题标题】:R: Reorder columns from dcast output numerically instead of lexicographicallyR:以数字方式而不是按字典顺序从 dcast 输出重新排序列
【发布时间】:2014-12-10 23:24:41
【问题描述】:

这是关于对包含数字和文本的列名称进行排序。我有一个来自 dcast 的数据框,有 200 行。我的订购有问题。

列名格式如下:

names(DF) <- c('Testname1.1', 'Testname1.100','Testname1.11','Testname1.2',...,Testname2.99)

编辑:我想将列排序为:

names(DF) <- c('Testname1.1, Testname1.2,Testname1.3,...Testname1.100,Testname2.1,...Testname 2.100)

原始输入有一个指定日期的列,但是当我“转换”数据时没有使用它。有没有办法指定“dcast”函数以数字方式对组合列名进行排序?

在 R 中按我需要的顺序排列列的最简单方法是什么?

非常感谢!

【问题讨论】:

    标签: r plyr


    【解决方案1】:

    我认为您需要先拆分列,然后才能使用它对数据框进行排序:

    library("reshape2")  ## for colsplit()
    library("gtools")
    

    构建测试数据:

    dat <- data.frame(matrix(1:25,5))
    names(dat) <- c('Testname1.1', 'Testname1.100',
         'Testname1.11','Testname1.2','Testname2.99')
    

    拆分和排序:

    cdat <- colsplit(names(dat),"\\.",c("name","num"))
    dat[,order(mixedorder(cdat$name),cdat$num)]
    
    ##   Testname1.1 Testname1.2 Testname1.11 Testname1.100 Testname2.99
    ## 1           1          16           11             6           21
    ## 2           2          17           12             7           22
    ## 3           3          18           13             8           23
    ## 4           4          19           14             9           24
    ## 5           5          20           15            10           25
    

    上面的mixedorder()(借用自@BondedDust 的答案)对于这个例子来说并不是真正必要的,但如果第一个(Testnamexx)组件有超过9个元素,那么Testname1,@987654327就需要@ 和 Testname10 将按正确的顺序出现。

    【讨论】:

    • (+1) 我也是这么想的
    • 仍然需要在第二个项目周围添加as.numeric,因为字典排序会使“100”
    • 我假设有多个测试,所以需要混合顺序才能在各种测试名称中排序
    • colsplit 实际上似乎自动将其第二列返回为数字
    【解决方案2】:

    pkg:gtools 的混合顺序和混合排序功能有时会做需要的事情,但在这种情况下,我认为句点分隔符会搞砸事情,因为它是数值的一部分。但显然是打算成为分隔符而不是小数点。试试

        nvec <- c('Testname1.1', 'Testname1.100', 'Testname1.11', 'Testname1.2', 'Testname2.99')
    #------------
    > require(gtools)
    Loading required package: gtools
    
    Attaching package: ‘gtools’
    
    The following objects are masked from ‘package:boot’:
    
        inv.logit, logit
    #------------
    myvec <- nvec[order( mixedorder( sapply(strsplit(nvec, "\\."), "[[", 1)),
                      as.numeric(sapply(strsplit(nvec, "\\."), "[[", 2))  )
                  ]
    

    【讨论】:

      【解决方案3】:

      一种方法是:

      library(gtools) #use gtools library
      library(NCmisc) #use NCmisc library for pad.left()
      
      myvec <- c('Testname1.1', 'Testname1.100','Testname1.11','Testname1.2','Testname2.99') #construct your vector
      
      myvec[mixedorder(  paste(substring(myvec,1,9), pad.left(substring(myvec,11,100),'0') , sep='')  ) ] 
      
      [1] "Testname1.1"   "Testname1.2"   "Testname1.11"  "Testname1.100" "Testname2.99"
      

      【讨论】:

      • 我只是因为提到 gtools::mixedsort 而投票赞成,但如果它按预期工作,则不需要使用 substr。
      • 嗯,是的,你是对的。我会看看并尽快修复。谢谢。混合顺序对我也有很大帮助。
      • 今天早上头脑清醒了一点,这看起来也像是一个解决方案。感谢您之前发现我的错误。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-17
      • 2014-05-27
      • 2020-07-04
      • 1970-01-01
      • 2010-10-24
      相关资源
      最近更新 更多