【问题标题】:dplyr: arrange columns by position in NSEdplyr:在 NSE 中按位置排列列
【发布时间】:2021-05-26 00:02:06
【问题描述】:

我想使用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))

我猜这种差异与arrange 使用的data-maskingselect 使用的tidy-select 之间的差异有关,但我不知道是否有办法选择列按arrange 中的位置。任何建议,将不胜感激。谢谢。

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    使用 dplyr >v1.0,您可以使用 across() 按索引指定列。你可以这样做

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

    【讨论】:

      【解决方案2】:

      您有几个选项,您可以使用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 (v2.0.0) 于 2021-05-25 创建

      有了这个你可以使用tidyselect函数来避免使用NSE。

      【讨论】:

      • across 是我想要的。谢谢!
      猜你喜欢
      • 2017-07-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-20
      • 2015-07-04
      • 1970-01-01
      相关资源
      最近更新 更多