使用 dplyr 按所有列排列数据框
Arrange data frame by all columns using dplyr
我正在生成 1s 和 0s 的数据帧,如下所示:
library(tidyverse)
library(glue)
num_var <- 3
rep(list(c(0L, 1L)), num_var) %>%
set_names(glue("var_{seq_len(num_var)}")) %>%
expand.grid() %>%
mutate(total = rowSums(.)) %>%
select(total, everything()) %>%
arrange(total, desc(var_1, var_2, var_3))
#> total var_1 var_2 var_3
#> 1 0 0 0 0
#> 2 1 1 0 0
#> 3 1 0 1 0
#> 4 1 0 0 1
#> 5 2 1 1 0
#> 6 2 1 0 1
#> 7 2 0 1 1
#> 8 3 1 1 1
由 reprex 创建于 2018-01-08
包 (v0.1.1.9000).
我需要按升序排列变量的总和,然后按降序排列每个变量。使用 dplyr::arrange()
非常简单。但是,我想有一个更强大的安排方法。例如,如果 num_var
更改为,则最后一行也必须更改为 arrange(total, desc(var_1, var_2, var_3, var_4))
。我尝试使用 tidy select 或 everything()
来安排,就像我使用 select()
函数一样,但是这个错误:
library(tidyverse)
library(glue)
num_var <- 3
rep(list(c(0L, 1L)), num_var) %>%
set_names(glue("var_{seq_len(num_var)}")) %>%
expand.grid() %>%
mutate(total = rowSums(.)) %>%
select(total, everything()) %>%
arrange(total, desc(everything()))
#> Error in arrange_impl(.data, dots): Evaluation error: No tidyselect variables were registered.
由 reprex 创建于 2018-01-08
包 (v0.1.1.9000).
有没有办法select变量不用直接命名就可以排列?
arrange
似乎不能直接与 select 辅助函数一起使用。您可以使用 arrange_at
、total
升序排列,除 total
之外的其他变量(select 使用 -one_of("total")
)降序排列:
arrange_at(vars(total, desc(-one_of("total"))))
# total var_1 var_2 var_3
#1 0 0 0 0
#2 1 1 0 0
#3 1 0 1 0
#4 1 0 0 1
#5 2 1 1 0
#6 2 1 0 1
#7 2 0 1 1
#8 3 1 1 1
可以使用此代码按每列从左到右排列
library(magrittr) ; library(rlang) ; library(dplyr)
data %>% arrange(!!!syms(colnames(.)))
这是可行的,因为 arrangement 不接受 tidyselect 语法,因此必须为每个名称传递符号(或者也可能是字符串)
对于较新版本的 dplyr
,您现在可以使用 across
:
library(dplyr)
#>
#> 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
iris %>%
arrange(across(everything(), desc)) %>%
head()
#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#> 1 7.9 3.8 6.4 2.0 virginica
#> 2 7.7 3.8 6.7 2.2 virginica
#> 3 7.7 3.0 6.1 2.3 virginica
#> 4 7.7 2.8 6.7 2.0 virginica
#> 5 7.7 2.6 6.9 2.3 virginica
#> 6 7.6 3.0 6.6 2.1 virginica
all.equal(iris %>%
arrange(across(everything(), desc)) ,
iris %>%
arrange(desc(Sepal.Length), desc(Sepal.Width), desc(Petal.Length), desc(Petal.Width), desc(Species)))
#> [1] TRUE
由 reprex package (v2.0.1)
于 2022-02-07 创建
我正在生成 1s 和 0s 的数据帧,如下所示:
library(tidyverse)
library(glue)
num_var <- 3
rep(list(c(0L, 1L)), num_var) %>%
set_names(glue("var_{seq_len(num_var)}")) %>%
expand.grid() %>%
mutate(total = rowSums(.)) %>%
select(total, everything()) %>%
arrange(total, desc(var_1, var_2, var_3))
#> total var_1 var_2 var_3
#> 1 0 0 0 0
#> 2 1 1 0 0
#> 3 1 0 1 0
#> 4 1 0 0 1
#> 5 2 1 1 0
#> 6 2 1 0 1
#> 7 2 0 1 1
#> 8 3 1 1 1
由 reprex 创建于 2018-01-08 包 (v0.1.1.9000).
我需要按升序排列变量的总和,然后按降序排列每个变量。使用 dplyr::arrange()
非常简单。但是,我想有一个更强大的安排方法。例如,如果 num_var
更改为,则最后一行也必须更改为 arrange(total, desc(var_1, var_2, var_3, var_4))
。我尝试使用 tidy select 或 everything()
来安排,就像我使用 select()
函数一样,但是这个错误:
library(tidyverse)
library(glue)
num_var <- 3
rep(list(c(0L, 1L)), num_var) %>%
set_names(glue("var_{seq_len(num_var)}")) %>%
expand.grid() %>%
mutate(total = rowSums(.)) %>%
select(total, everything()) %>%
arrange(total, desc(everything()))
#> Error in arrange_impl(.data, dots): Evaluation error: No tidyselect variables were registered.
由 reprex 创建于 2018-01-08 包 (v0.1.1.9000).
有没有办法select变量不用直接命名就可以排列?
arrange
似乎不能直接与 select 辅助函数一起使用。您可以使用 arrange_at
、total
升序排列,除 total
之外的其他变量(select 使用 -one_of("total")
)降序排列:
arrange_at(vars(total, desc(-one_of("total"))))
# total var_1 var_2 var_3
#1 0 0 0 0
#2 1 1 0 0
#3 1 0 1 0
#4 1 0 0 1
#5 2 1 1 0
#6 2 1 0 1
#7 2 0 1 1
#8 3 1 1 1
可以使用此代码按每列从左到右排列
library(magrittr) ; library(rlang) ; library(dplyr)
data %>% arrange(!!!syms(colnames(.)))
这是可行的,因为 arrangement 不接受 tidyselect 语法,因此必须为每个名称传递符号(或者也可能是字符串)
对于较新版本的 dplyr
,您现在可以使用 across
:
library(dplyr)
#>
#> 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
iris %>%
arrange(across(everything(), desc)) %>%
head()
#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#> 1 7.9 3.8 6.4 2.0 virginica
#> 2 7.7 3.8 6.7 2.2 virginica
#> 3 7.7 3.0 6.1 2.3 virginica
#> 4 7.7 2.8 6.7 2.0 virginica
#> 5 7.7 2.6 6.9 2.3 virginica
#> 6 7.6 3.0 6.6 2.1 virginica
all.equal(iris %>%
arrange(across(everything(), desc)) ,
iris %>%
arrange(desc(Sepal.Length), desc(Sepal.Width), desc(Petal.Length), desc(Petal.Width), desc(Species)))
#> [1] TRUE
由 reprex package (v2.0.1)
于 2022-02-07 创建