跨多个变量粘贴变量名称及其向量值
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_dfc
或 apply
.
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))
假设我有这个数据框:
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_dfc
或 apply
.
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))