str_replace 位于 mutate 内的 fct_reorder(across())

问题描述 投票:0回答:1

假设我有这个小玩意:

df <- tibble::tribble(
  ~how_bright_txt, ~how_bright_num,   ~how_hard_txt, ~how_hard_num, ~how_hot_txt, ~how_hot_num,
  "Not very much",              1L,   "Really hard",            5L,       "Cold",           1L,
       "Somewhat",              2L, "Somewhat hard",            2L, "A bit cold",           2L,
         "Medium",              3L,        "Medium",            3L,     "Medium",           3L,
    "Quite a bit",              4L,    "Quite hard",            4L,  "Quite hot",           4L,
          "A lot",              5L, "Not very hard",            1L, "Really hot",           5L
  )

我想创建以现有列名称的第一部分命名的新列(减去

_txt
_num
前缀),并采用
_txt
列的值,但将它们转换为按相应
 排序的因子_num
列。

我可以通过在每列的

fct_reorder
内重复
mutate
来完成此操作,如下所示:

require(tidyverse)

df %>% 
    mutate(how_bright = fct_reorder(how_bright_txt, -how_bright_num),
           how_hard = fct_reorder(how_hard_txt, -how_hard_num),
           how_hot = fct_reorder(how_hot_txt, -how_hot_num)) %>%
    select(-c(ends_with("_txt"), ends_with("_num")))

但我想简化这个并使用

mutate(across())
。所以我尝试这样做:

df %>% 
    mutate(across(ends_with("_txt"), 
         ~ fct_reorder(.x, str_replace(.x, "_txt", "_num")), 
                     .names = '{stringr::str_remove({col}, "_txt")}')) %>%
    select(-c(ends_with("_txt"), ends_with("_num")))

但是 结果因子(

how_bright
how_hard
how_hot
)的顺序不正确
,并且与原始
_num
列中的顺序不对应。我也尝试用
str_replace
调用替换
gsub
调用,但我得到相同的输出

有人能看出我做错了什么吗?

r dataframe dplyr r-factor across
1个回答
1
投票

您需要的是

cur_column()
get()

library(tidyverse)

df %>% 
  mutate(across(ends_with("_txt"), 
                ~ fct_reorder(.x, get(str_replace(cur_column(), "_txt", "_num"))),
                .names = "{str_remove(.col, '_txt')}"),
         .keep = "unused")

# # A tibble: 5 × 3
#   how_bright    how_hard      how_hot   
#   <fct>         <fct>         <fct>     
# 1 Not very much Really hard   Cold      
# 2 Somewhat      Somewhat hard A bit cold
# 3 Medium        Medium        Medium    
# 4 Quite a bit   Quite hard    Quite hot 
# 5 A lot         Not very hard Really hot
© www.soinside.com 2019 - 2024. All rights reserved.