跨多个变量粘贴变量名称及其向量值

Pasting variable name with its vector value across multiple variables

假设我有这个数据框:

library(dplyr)

set.seed(1)
df <- tibble(sol_1 = sample(1:4, 10, replace = TRUE),
             sol_2 = sample(1:4, 10, replace = TRUE))

# A tibble: 10 x 2
   sol_1 sol_2
   <int> <int>
 1     1     3
 2     4     3
 3     3     1
 4     1     1
 5     2     1
 6     1     2
 7     3     2
 8     3     2
 9     2     2
10     2     3

我想更改变量中的值以包含它们各自的变量名称,如下所示:

# A tibble: 10 x 2
         sol_1       sol_2
         <chr>       <chr>
 1     sol_1_1     sol_2_3
 2     sol_1_4     sol_2_3
 3     sol_1_3     sol_2_1
 4     sol_1_1     sol_2_1
 5     sol_1_2     sol_2_1
 6     sol_1_1     sol_2_2
 7     sol_1_3     sol_2_2
 8     sol_1_3     sol_2_2
 9     sol_1_2     sol_2_2
10     sol_1_2     sol_2_3

哪个rlang变量会指示使用变量名作为字符串?我尝试了类似以下的操作:

mutate_at(df, vars(starts_with("sol")), ~ paste(rlang::as_string(.x), .x, sep = "_"))

但显然我用错了函数。

使用 mutate_* 很难完成此任务,因为它只传递没有名称的列的值。相反,我们可以尝试 map_dfcapply.

library(dplyr)
library(purrr)
nms = grep("sol", names(df), value = TRUE)
map_dfc(nms, ~transmute(df, !!quo_name(.x) := paste0(.x,'_',!!sym(.x))))

使用基数 R

df[ ,nms] = t(apply(df[,nms], 1, function(x) paste0(names(x),'_',x)))

您可以使用 mutate 实现相同的目的:

library(dplyr)
    df %>% mutate(sol_1 = paste0(names(df)[1], '_', sol_1),
                  sol_2 = paste0(names(df)[2], '_', sol_2))

另一种选择是重塑成'long',然后变形后变回'wide'

library(dplyr)
library(tidyr)
library(stringr)
df %>%
   mutate(rn = row_number()) %>% 
   pivot_longer(cols = -rn) %>% 
   mutate(value = str_c(name, value, sep="_")) %>% 
   pivot_wider(names_from = name, values_from = value) %>%
   select(-rn)
# A tibble: 10 x 2
#   sol_1   sol_2  
#   <chr>   <chr>  
# 1 sol_1_1 sol_2_3
# 2 sol_1_4 sol_2_3
# 3 sol_1_3 sol_2_1
# 4 sol_1_1 sol_2_1
# 5 sol_1_2 sol_2_1
# 6 sol_1_1 sol_2_2
# 7 sol_1_3 sol_2_2
# 8 sol_1_3 sol_2_2
# 9 sol_1_2 sol_2_2
#10 sol_1_2 sol_2_3

或使用imap

library(purrr)
imap(df, ~ str_c(.y, .x, sep="_"))

基础 R 解决方案:

df[] <- lapply(seq_along(df),

               function(x){df[,x] <- paste0(names(df[c(x)]), "_", unlist(df[c(x)]))})

数据:

df <- tibble(sol_1 = sample(1:4, 10, replace = TRUE),

             sol_2 = sample(1:4, 10, replace = TRUE))