【问题标题】:Order column names in ascending order within dplyr chain在 dplyr 链中按升序排列列名
【发布时间】:2016-10-27 20:17:34
【问题描述】:

我有这个data.frame:

df <- structure(list(att_number = structure(1:3, .Label = c("0", "1", 
                                                      "2"), class = "factor"), `1` = structure(c(2L, 3L, 1L), .Label = c("1026891", 
                                                                                                                         "412419", "424869"), class = "factor"), `10` = structure(c(2L, 
                                                                                                                                                                                    1L, 3L), .Label = c("235067", "546686", "92324"), class = "factor"), 
               `2` = structure(c(3L, 1L, 2L), .Label = c("12729", "7569", 
                                                         "9149"), class = "factor")), .Names = c("att_number", "1", 
                                                                                                 "10", "2"), row.names = c(NA, -3L), class = "data.frame")    

看起来像这样以数字作为列名。

att_number  1         10        2
         0  412419    546686    9149
         1  424869    235067    12729
         2  1026891   92324     7569

在 dplyr 链中,我想按升序对列进行排序,如下所示:

att_number  1       2      10
         0  412419  9149   546686
         1  424869  12729  235067
         2  1026891 7569   7569

我尝试过使用select_,但它不想按计划工作。关于我如何做到这一点的任何想法?这是我微弱的尝试:

names_order <- names(df)[-1] %>%
  as.numeric %>%
  .[order(.)] %>%
  as.character %>%
  c('att_number', .)

df %>%
  select_(.dots = names_order)

Error: Position must be between 0 and n

【问题讨论】:

  • 为什么不.[ order(as.numeric(names(.))) ]
  • 我想在 LHS 上保留以字母开头的列。我可以通过添加另一个管道来做到这一点:select(att_number, everything()),但如果可能的话,我想避免使用另一个管道......

标签: r dplyr chain


【解决方案1】:

更新

对于较新版本的 dplyr (>= 0.7.0):

library(tidyverse)

sort_names <- function(data) {
  name  <- names(data)
  chars <- keep(name, grepl, pattern = "[^0-9]") %>% sort()
  nums  <- discard(name, grepl, pattern = "[^0-9]") %>% 
    as.numeric() %>% 
    sort() %>% 
    sprintf("%s", .)

  select(data, !!!c(chars, nums))
}

sort_names(df)

原创

您需要在数字列名称周围加上反引号,以阻止 select 尝试将它们解释为列位置:

library(tidyverse)

sort_names <- function(data) {
  name  <- names(data)
  chars <- keep(name, grepl, pattern = "[^0-9]") %>% sort()
  nums  <- discard(name, grepl, pattern = "[^0-9]") %>% 
             as.numeric() %>% 
             sort() %>% 
             sprintf("`%s`", .)

  select_(data, .dots = c(chars, nums))
}

sort_names(df)

【讨论】:

  • 你能更新这个答案吗?它似乎不再起作用了!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-07-04
  • 2017-11-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-11
相关资源
最近更新 更多