如何将变异的列重新定位到原始列旁边?
How can I relocate mutated columns next to the original colums?
我创建了一个函数,该函数跨列变异并从每个列创建新的命名列。新列放在数据框的右侧,而我想让它们与每个原始列相邻。我正在寻找一种解决方案,该解决方案可以推广到可能使用此函数的任何数据框,编写 select 语句来重新排序列对于我的用例来说不够自动。
test_data <- data.frame(data_col_1 = c(1,2,3),
data_col_2 = c(1,2,3),
data_col_3 = c(1,2,3),
another_column = c("a","b","c"))
perc_funct <- function(df, columns, numerator){
p_f <- function(x, numerator){
(x/numerator)*100
}
j <- df %>%
mutate( across({{columns}},
.fns = list(perc = ~p_f(.x, numerator)),
.names = "{col}_{fn}"))# need to figure out a way to get the columns ordered
return(j)
}
test_data %>% perc_funct(columns = starts_with("data"), numerator = 1)
输出当前将所有新列放在右侧。
"data_col_1" "data_col_2" "data_col_3" "another_column" "data_col_1_perc" "data_col_2_perc" " data_col_3_perc
我想要的输出将每个新列放在每个旧列的右侧。
"data_col_1" "data_col_1_perc" "data_col_2" "data_col_2_perc" "data_col_3" "data_col_3_perc" "another_column
之后我通常使用 select(sort(names(.)))
对列进行排序:
library(dplyr)
test_data %>%
perc_funct(columns = starts_with("data"), numerator = 1) %>%
select(sort(names(.)))
#> data_col_1 data_col_1_perc data_col_2 data_col_2_perc data_col_3
#> 1 1 100 1 100 1
#> 2 2 200 2 200 2
#> 3 3 300 3 300 3
#> data_col_3_perc
#> 1 100
#> 2 200
#> 3 300
由 reprex package (v2.0.1)
于 2022-04-01 创建
如果我想在同一位置保留其他列怎么办?
这只是将我的解决方案与其他 select
语句或 dplyr 动词嵌套在一起的问题。作为中间步骤,您可能必须保存包含未排序列的数据框。
示例 1
这是一个包含其他三列的示例,其中一些列在前面,一些列在最后,其他列在任何地方但都放在一起。
library(dplyr)
df <-
test_data %>%
mutate(first_col = 1, other_columns = 100, last_col = 999) %>%
perc_funct(columns = starts_with("data"), numerator = 1)
# Unsorted:
df %>% names()
#> [1] "data_col_1" "data_col_2" "data_col_3" "first_col"
#> [5] "other_columns" "last_col" "data_col_1_perc" "data_col_2_perc"
#> [9] "data_col_3_perc"
# Sorted:
df %>%
select(
first_col,
df %>% select(starts_with("data")) %>% names() %>% sort(),
everything(),
last_col
)
#> first_col data_col_1 data_col_1_perc data_col_2 data_col_2_perc data_col_3
#> 1 1 1 100 1 100 1
#> 2 1 2 200 2 200 2
#> 3 1 3 300 3 300 3
#> data_col_3_perc other_columns last_col
#> 1 100 100 999
#> 2 200 100 999
#> 3 300 100 999
由 reprex package (v2.0.1)
于 2022-04-01 创建
示例 2
还有一个替代方案使用 col_bind()
:
如果您只想将新列放在最后,但与创建它们的列一起排序,您还可以执行以下操作:
library(dplyr)
df %>%
select(
-starts_with("data")
) %>% bind_cols(
df %>%
select(
df %>% select(starts_with("data")) %>% names() %>% sort()
)
)
#> first_col other_columns last_col data_col_1 data_col_1_perc data_col_2
#> 1 1 100 999 1 100 1
#> 2 1 100 999 2 200 2
#> 3 1 100 999 3 300 3
#> data_col_2_perc data_col_3 data_col_3_perc
#> 1 100 1 100
#> 2 200 2 200
#> 3 300 3 300
使用 dplyr(自版本 1.0.0 起)移动列的推荐方法是使用 relocate()
。 relocate()
支持 tidyselect 语义,但重要的是仅对选定的列起作用,而将所有其他列留在原地。在您的情况下,您可以在以 data
.
开头的列上 grep()
和 sort()
test_data <- data.frame(column_1 = 1:3,
data_col_1 = c(1,2,3),
data_col_2 = c(1,2,3),
data_col_3 = c(1,2,3),
another_column = c("a","b","c"))
test_data %>%
perc_funct(columns = starts_with("data"), numerator = 1) %>%
relocate(sort(grep("^data", names(.), value = TRUE)), .before = data_col_1)
column_1 data_col_1 data_col_1_perc data_col_2 data_col_2_perc data_col_3 data_col_3_perc another_column
1 1 1 100 1 100 1 100 a
2 2 2 200 2 200 2 200 b
3 3 3 300 3 300 3 300 c
.before
(或.after
)参数指定重定位列的位置,在这种情况下,您可以将它们放在 data_col_1
.
之前
另一种可能性是使用 contains()
和原始数据帧中的列顺序
test_data <- data.frame(column_1 = 1:3,
data_col_1 = c(1,2,3),
data_col_2 = c(1,2,3),
data_col_3 = c(1,2,3),
another_column = c("a","b","c"))
test_data %>% perc_funct(columns = starts_with("data"), numerator = 1) %>%
select(contains(test_data %>% colnames()))
我创建了一个函数,该函数跨列变异并从每个列创建新的命名列。新列放在数据框的右侧,而我想让它们与每个原始列相邻。我正在寻找一种解决方案,该解决方案可以推广到可能使用此函数的任何数据框,编写 select 语句来重新排序列对于我的用例来说不够自动。
test_data <- data.frame(data_col_1 = c(1,2,3),
data_col_2 = c(1,2,3),
data_col_3 = c(1,2,3),
another_column = c("a","b","c"))
perc_funct <- function(df, columns, numerator){
p_f <- function(x, numerator){
(x/numerator)*100
}
j <- df %>%
mutate( across({{columns}},
.fns = list(perc = ~p_f(.x, numerator)),
.names = "{col}_{fn}"))# need to figure out a way to get the columns ordered
return(j)
}
test_data %>% perc_funct(columns = starts_with("data"), numerator = 1)
输出当前将所有新列放在右侧。
"data_col_1" "data_col_2" "data_col_3" "another_column" "data_col_1_perc" "data_col_2_perc" " data_col_3_perc
我想要的输出将每个新列放在每个旧列的右侧。 "data_col_1" "data_col_1_perc" "data_col_2" "data_col_2_perc" "data_col_3" "data_col_3_perc" "another_column
之后我通常使用 select(sort(names(.)))
对列进行排序:
library(dplyr)
test_data %>%
perc_funct(columns = starts_with("data"), numerator = 1) %>%
select(sort(names(.)))
#> data_col_1 data_col_1_perc data_col_2 data_col_2_perc data_col_3
#> 1 1 100 1 100 1
#> 2 2 200 2 200 2
#> 3 3 300 3 300 3
#> data_col_3_perc
#> 1 100
#> 2 200
#> 3 300
由 reprex package (v2.0.1)
于 2022-04-01 创建如果我想在同一位置保留其他列怎么办?
这只是将我的解决方案与其他 select
语句或 dplyr 动词嵌套在一起的问题。作为中间步骤,您可能必须保存包含未排序列的数据框。
示例 1
这是一个包含其他三列的示例,其中一些列在前面,一些列在最后,其他列在任何地方但都放在一起。
library(dplyr)
df <-
test_data %>%
mutate(first_col = 1, other_columns = 100, last_col = 999) %>%
perc_funct(columns = starts_with("data"), numerator = 1)
# Unsorted:
df %>% names()
#> [1] "data_col_1" "data_col_2" "data_col_3" "first_col"
#> [5] "other_columns" "last_col" "data_col_1_perc" "data_col_2_perc"
#> [9] "data_col_3_perc"
# Sorted:
df %>%
select(
first_col,
df %>% select(starts_with("data")) %>% names() %>% sort(),
everything(),
last_col
)
#> first_col data_col_1 data_col_1_perc data_col_2 data_col_2_perc data_col_3
#> 1 1 1 100 1 100 1
#> 2 1 2 200 2 200 2
#> 3 1 3 300 3 300 3
#> data_col_3_perc other_columns last_col
#> 1 100 100 999
#> 2 200 100 999
#> 3 300 100 999
由 reprex package (v2.0.1)
于 2022-04-01 创建示例 2
还有一个替代方案使用 col_bind()
:
如果您只想将新列放在最后,但与创建它们的列一起排序,您还可以执行以下操作:
library(dplyr)
df %>%
select(
-starts_with("data")
) %>% bind_cols(
df %>%
select(
df %>% select(starts_with("data")) %>% names() %>% sort()
)
)
#> first_col other_columns last_col data_col_1 data_col_1_perc data_col_2
#> 1 1 100 999 1 100 1
#> 2 1 100 999 2 200 2
#> 3 1 100 999 3 300 3
#> data_col_2_perc data_col_3 data_col_3_perc
#> 1 100 1 100
#> 2 200 2 200
#> 3 300 3 300
使用 dplyr(自版本 1.0.0 起)移动列的推荐方法是使用 relocate()
。 relocate()
支持 tidyselect 语义,但重要的是仅对选定的列起作用,而将所有其他列留在原地。在您的情况下,您可以在以 data
.
grep()
和 sort()
test_data <- data.frame(column_1 = 1:3,
data_col_1 = c(1,2,3),
data_col_2 = c(1,2,3),
data_col_3 = c(1,2,3),
another_column = c("a","b","c"))
test_data %>%
perc_funct(columns = starts_with("data"), numerator = 1) %>%
relocate(sort(grep("^data", names(.), value = TRUE)), .before = data_col_1)
column_1 data_col_1 data_col_1_perc data_col_2 data_col_2_perc data_col_3 data_col_3_perc another_column
1 1 1 100 1 100 1 100 a
2 2 2 200 2 200 2 200 b
3 3 3 300 3 300 3 300 c
.before
(或.after
)参数指定重定位列的位置,在这种情况下,您可以将它们放在 data_col_1
.
另一种可能性是使用 contains()
和原始数据帧中的列顺序
test_data <- data.frame(column_1 = 1:3,
data_col_1 = c(1,2,3),
data_col_2 = c(1,2,3),
data_col_3 = c(1,2,3),
another_column = c("a","b","c"))
test_data %>% perc_funct(columns = starts_with("data"), numerator = 1) %>%
select(contains(test_data %>% colnames()))