代码之家  ›  专栏  ›  技术社区  ›  Josh

dplyr:在NSE中按位置排列列

  •  0
  • Josh  · 技术社区  · 5 年前

    我想用 dplyr::arrange 根据特定列中的值对数据帧的行进行排序。我想根据位置而不是列名来选择列,因为列名会根据输入而变化。我试着把这些建议改为 dplyr::select 在这里找到的( dplyr: select columns by position in NSE ),但我的代码只返回原始数据帧,没有任何更改。这是我的数据框和我用来排序的代码:

    df <- structure(list(D7_ctrl_v_D6_ctrl_deg = structure(c(1L, 2L, 3L, 
    1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 
    2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L), .Label = c("down", "unchanged", 
    "up"), class = "factor"), D7_OE_v_D7_ctrl_deg = structure(c(1L, 
    1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L, 1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 
    3L, 1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L), .Label = c("down", "unchanged", 
    "up"), class = "factor"), D7_OE_v_D6_ctrl_deg = structure(c(1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
    2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L), .Label = c("down", "unchanged", 
    "up"), class = "factor"), Freq = c(584L, 1841L, 375L, 636L, 331L, 
    0L, 44L, 0L, 0L, 0L, 420L, 600L, 208L, 9164L, 280L, 391L, 410L, 
    0L, 0L, 0L, 69L, 0L, 448L, 746L, 297L, 2362L, 715L)), class = "data.frame", row.names = c(NA, 
    -27L))
    
    ## these all fail
    df %>% dplyr::arrange(1)
    df %>% dplyr::arrange(c(1))
    df %>% dplyr::arrange(!!"1")
    df %>% dplyr::arrange(!!c(1))
    

    我猜两者之间的差异与 data-masking arrange tidy-select 使用人 select ,但我不知道是否有一种方法可以在 . 如有任何建议,将不胜感激。谢谢。

    2 回复  |  直到 5 年前
        1
  •  1
  •   Justin Landis    5 年前

    你有一些选择,你可以使用作用域函数,比如 arrange_at 这将允许您指定位置的数字向量:

    library(dplyr)
    #> Warning: package 'dplyr' was built under R version 3.6.3
    #> 
    #> Attaching package: 'dplyr'
    #> The following objects are masked from 'package:stats':
    #> 
    #>     filter, lag
    #> The following objects are masked from 'package:base':
    #> 
    #>     intersect, setdiff, setequal, union
    
    df <- iris
    num_vec <- c(3,1)
    df %>% arrange_at(1) %>% head()
    #>   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
    #> 1          4.3         3.0          1.1         0.1  setosa
    #> 2          4.4         2.9          1.4         0.2  setosa
    #> 3          4.4         3.0          1.3         0.2  setosa
    #> 4          4.4         3.2          1.3         0.2  setosa
    #> 5          4.5         2.3          1.3         0.3  setosa
    #> 6          4.6         3.1          1.5         0.2  setosa
    df %>% arrange_at(num_vec) %>% head()
    #>   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
    #> 1          4.6         3.6          1.0         0.2  setosa
    #> 2          4.3         3.0          1.1         0.1  setosa
    #> 3          5.0         3.2          1.2         0.2  setosa
    #> 4          5.8         4.0          1.2         0.2  setosa
    #> 5          4.4         3.0          1.3         0.2  setosa
    #> 6          4.4         3.2          1.3         0.2  setosa
    

    或者,您可以使用新函数来替代范围变量 across

    df %>% arrange(across(1)) %>% head()
    #>   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
    #> 1          4.3         3.0          1.1         0.1  setosa
    #> 2          4.4         2.9          1.4         0.2  setosa
    #> 3          4.4         3.0          1.3         0.2  setosa
    #> 4          4.4         3.2          1.3         0.2  setosa
    #> 5          4.5         2.3          1.3         0.3  setosa
    #> 6          4.6         3.1          1.5         0.2  setosa
    df %>% arrange(across(all_of(num_vec))) %>% head()
    #>   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
    #> 1          4.6         3.6          1.0         0.2  setosa
    #> 2          4.3         3.0          1.1         0.1  setosa
    #> 3          5.0         3.2          1.2         0.2  setosa
    #> 4          5.8         4.0          1.2         0.2  setosa
    #> 5          4.4         3.0          1.3         0.2  setosa
    #> 6          4.4         3.2          1.3         0.2  setosa
    

    reprex package (2.0.0版)

    有了这个你就可以使用 tidyselect

        2
  •  2
  •   MrFlick    5 年前

    带dplyr>v1.0您可以使用 across() 按索引指定列。你能做到的

    df %>% dplyr::arrange(across(1))