使用 dplyr 将函数应用于一行中的选定列

Apply function to selected columns in a row with dplyr

新的 dplyr 版本 1.0.0 使其成为 easier to work with rows

across 允许在整个列上应用一个函数,用 dplyrverbs 选择,例如 sorteverything() :

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

selected 列

df %>% 
  rowwise %>% 
  transmute(V1, V2, sortlist = list(sort(c_across(V3:V5)))) %>% 
  unnest_wider(c(sortlist)) %>%
  set_names(names(df))