使用 dplyr 将函数应用于一行中的选定列
Apply function to selected columns in a row with dplyr
新的 dplyr
版本 1.0.0 使其成为 easier to work with rows。
across
允许在整个列上应用一个函数,用 dplyr
verbs 选择,例如 sort
和 everything()
:
set.seed(1)
df <- as.data.frame(matrix(sample.int(5, 25, TRUE), 5, 5))
df
V1 V2 V3 V4 V5
1 1 3 5 5 5
2 4 2 5 5 2
3 1 3 2 1 2
4 2 3 2 1 1
5 5 1 1 5 4
df %>% mutate(across(everything(),sort))
V1 V2 V3 V4 V5
1 1 1 1 1 1
2 1 2 2 1 2
3 2 3 2 5 2
4 4 3 5 5 4
5 5 3 5 5 5
同样,我想在行中的选定列上应用一个函数,利用更新的 rowwise
dplyr
功能,无需转置数据帧.
我找到的最接近的解决方案使用 c_across
:
df %>% rowwise %>%
mutate(sortlist = list(sort(c_across(everything())))) %>%
unnest_wider(sortlist)
# A tibble: 5 x 10
V1 V2 V3 V4 V5 ...1 ...2 ...3 ...4 ...5
<int> <int> <int> <int> <int> <int> <int> <int> <int> <int>
1 1 3 5 5 5 1 3 5 5 5
2 4 2 5 5 2 2 2 4 5 5
3 1 3 2 1 2 1 1 2 2 3
4 2 3 2 1 1 1 1 2 2 3
5 5 1 1 5 4 1 1 4 5 5
但是有没有 dplyr
方式直接到达 :
V1 V2 V3 V4 V5
1 1 3 5 5 5
2 2 2 4 5 5
3 1 1 2 2 3
4 1 1 2 2 3
5 1 1 4 5 5
列也是如此吗?
我们可以直接用pmap
代替rowwise/c_across
两步
library(dplyr)
library(purrr)
df %>%
pmap_dfr(~ set_names(sort(c(...)), names(df)))
# A tibble: 5 x 5
# V1 V2 V3 V4 V5
# <int> <int> <int> <int> <int>
#1 1 3 5 5 5
#2 2 2 4 5 5
#3 1 1 2 2 3
#4 1 1 2 2 3
#5 1 1 4 5 5
或者如果我们使用 OP 的方法
library(tidyr)
df %>%
rowwise %>%
transmute(sortlist = list(sort(c_across(everything())))) %>%
unnest_wider(c(sortlist)) %>%
set_names(names(df))
# A tibble: 5 x 5
# V1 V2 V3 V4 V5
# <int> <int> <int> <int> <int>
#1 1 3 5 5 5
#2 2 2 4 5 5
#3 1 1 2 2 3
#4 1 1 2 2 3
#5 1 1 4 5 5
或 select
ed 列
df %>%
rowwise %>%
transmute(V1, V2, sortlist = list(sort(c_across(V3:V5)))) %>%
unnest_wider(c(sortlist)) %>%
set_names(names(df))
新的 dplyr
版本 1.0.0 使其成为 easier to work with rows。
across
允许在整个列上应用一个函数,用 dplyr
verbs 选择,例如 sort
和 everything()
:
set.seed(1)
df <- as.data.frame(matrix(sample.int(5, 25, TRUE), 5, 5))
df
V1 V2 V3 V4 V5
1 1 3 5 5 5
2 4 2 5 5 2
3 1 3 2 1 2
4 2 3 2 1 1
5 5 1 1 5 4
df %>% mutate(across(everything(),sort))
V1 V2 V3 V4 V5
1 1 1 1 1 1
2 1 2 2 1 2
3 2 3 2 5 2
4 4 3 5 5 4
5 5 3 5 5 5
同样,我想在行中的选定列上应用一个函数,利用更新的 rowwise
dplyr
功能,无需转置数据帧.
我找到的最接近的解决方案使用 c_across
:
df %>% rowwise %>%
mutate(sortlist = list(sort(c_across(everything())))) %>%
unnest_wider(sortlist)
# A tibble: 5 x 10
V1 V2 V3 V4 V5 ...1 ...2 ...3 ...4 ...5
<int> <int> <int> <int> <int> <int> <int> <int> <int> <int>
1 1 3 5 5 5 1 3 5 5 5
2 4 2 5 5 2 2 2 4 5 5
3 1 3 2 1 2 1 1 2 2 3
4 2 3 2 1 1 1 1 2 2 3
5 5 1 1 5 4 1 1 4 5 5
但是有没有 dplyr
方式直接到达 :
V1 V2 V3 V4 V5
1 1 3 5 5 5
2 2 2 4 5 5
3 1 1 2 2 3
4 1 1 2 2 3
5 1 1 4 5 5
列也是如此吗?
我们可以直接用pmap
代替rowwise/c_across
library(dplyr)
library(purrr)
df %>%
pmap_dfr(~ set_names(sort(c(...)), names(df)))
# A tibble: 5 x 5
# V1 V2 V3 V4 V5
# <int> <int> <int> <int> <int>
#1 1 3 5 5 5
#2 2 2 4 5 5
#3 1 1 2 2 3
#4 1 1 2 2 3
#5 1 1 4 5 5
或者如果我们使用 OP 的方法
library(tidyr)
df %>%
rowwise %>%
transmute(sortlist = list(sort(c_across(everything())))) %>%
unnest_wider(c(sortlist)) %>%
set_names(names(df))
# A tibble: 5 x 5
# V1 V2 V3 V4 V5
# <int> <int> <int> <int> <int>
#1 1 3 5 5 5
#2 2 2 4 5 5
#3 1 1 2 2 3
#4 1 1 2 2 3
#5 1 1 4 5 5
或 select
ed 列
df %>%
rowwise %>%
transmute(V1, V2, sortlist = list(sort(c_across(V3:V5)))) %>%
unnest_wider(c(sortlist)) %>%
set_names(names(df))