如何在 R 中的 paste() 中使用 dplyr 的 contains()?

How to use dplyr's contains() within paste() in R?

我有一长串列,并将得分列中的值合并为一列。但是,我不想将它们全部键入,而是只想在粘贴函数中使用 contains("test")——这可能吗?

这是我的数据以及我希望它看起来像什么:

library(dplyr)

#What I have :(
test <- tibble(id = c(1:2),
               test_score = c(4,5),
               test_building = c("Lupton", "Hearst"),
               initials = c("s", "j"))

#What I want ^_^
answer <- tibble(id = c(1:2),
                test_score = c(4,5),
                test_building = c("Lupton", "Hearst"),
               initials = c("s", "j"),
               test_combo = c("4, Lupton", "5, Hearst"))

这是我尝试过的一些失败尝试的墓地:

test %>% 
  mutate(test_combo = paste(vars(contains("test"))))

test %>% 
  mutate(test_combo = paste(across(contains("test"))))

我希望顺序是 test_score,然后是 test_building,但顺序真的不是那么重要,所以我会采取一个简单的解决方案,将它们正确粘贴到 'wrong' 顺序与将它们放入 'right' 顺序的非常复杂的路径。

一个复杂的解决方案可能是:

library(tidyr)
library(dplyr)

test %>% 
  mutate(across(starts_with("test_"), as.character)) %>% 
  pivot_longer(starts_with("test_")) %>% 
  group_by(id, initials) %>% 
  summarise(test_combo = paste(value, collapse = ", "), .groups = "drop") %>% 
  right_join(test, by = c("id", "initials"))

这个returns

# A tibble: 2 x 5
     id initials test_combo test_score test_building
  <int> <chr>    <chr>           <dbl> <chr>        
1     1 s        4, Lupton           4 Lupton       
2     2 j        5, Hearst           5 Hearst   

一个简单的方法可能是

test %>% 
  group_by(id) %>% 
  mutate(test_combo = paste(across(contains("test")), collapse = ", ")) %>% 
  ungroup()

哪个returns

# A tibble: 2 x 5
     id test_score test_building initials test_combo
  <int>      <dbl> <chr>         <chr>    <chr>     
1     1          4 Lupton        s        4, Lupton 
2     2          5 Hearst        j        5, Hearst 

我们可以将 pasteacross 结合使用 .names 参数和 unite 函数:

library(dplyr)
library(tidyr)

test %>% 
  mutate(across(contains("test"), ~paste(.), .names ="new_{.col}")) %>% 
  unite(test_combo, starts_with('new'), na.rm = TRUE, sep = ', ')

     id test_score test_building initials test_combo
  <int>      <dbl> <chr>         <chr>    <chr>     
1     1          4 Lupton        s        4, Lupton 
2     2          5 Hearst        j        5, Hearst 

替代

正如@AdroMine 和@Martin Gal(感谢他们两人)所指出的: 使用 unite:

library(tidyr)
test %>% unite(test_combo, contains("test"), remove = FALSE, sep = ", ")
     id test_combo test_score test_building initials
  <int> <chr>           <dbl> <chr>         <chr>   
1     1 4, Lupton           4 Lupton        s       
2     2 5, Hearst           5 Hearst        j