str_replace 在 mutate(across()) 中匹配来自 cur_column 的第 n 个字符
str_replace within mutate(across()) matching nth character from cur_column
我的目标总结
我有以下数据帧结构:
my.df <-data.frame("col1_A.C"=c("AA","AC","CC"),
"col2_A.T"=c("TT","AT","TT"),
"col3_C.G"=c("GG","CG","CG"))
my.df
# col1_A.C col2_A.T col1_C.G
# 1 AA TT GG
# 2 AC AT CG
# 3 CC TT CG
对于每一列,我想用字符“R”替换与列名的倒数第三个字符匹配的任何字符。
使用上面的数据框,我想得到这个:
my.df2 <- data.frame("col1_A.C"=c("RR","RC","CC"),
"col2_A.T"=c("TT","RT","TT"),
"col3_C.G"=c("GG","RG","RG"))
my.df2
# col1_A.C col2_A.T col1_C.G
# 1 RR TT GG
# 2 RC RT RG
# 3 CC TT RG
例如,在第一列中,列名是 col1_A.C,A 是倒数第三个字符。因此,所有 A 都被替换为 R。
到目前为止我的代码
为了实现这一点,我制作了以下代码
my.df2 <- my.df %>% mutate(across(.cols=everything(),
.funs=str_replace_all(.,
substr(cur_column(),
nchar(cur_column()-2),
nchar(cur_column()-2)
),
"R")
)
)
不幸的是,生成的数据帧 my.df2 看起来与 my.df 完全一样,并且没有字符替换发生了。虽然没有返回错误。
我已经通过以下方式测试了 str_replace_all() 方法,它适用于向量。我想我 missing/not 理解 str_replace_all() 在 mutate(across())[ 中的解释方式=48=]函数。
first.column <- c("CC","CT","CC")
first.column <- str_replace_all(first.column,
substr(colnames(my.df)[1],
nchar(colnames(my.df)[1])-2,
nchar(colnames(my.df)[1])-2
),
"R")
print(first.column)
# [1] "RR" "RT" "RR"
我 运行 不知道什么可能不起作用。我对 R 及其功能的理解不是很透彻,所以如果我遗漏了一些简单的东西,我深表歉意。我也搜索过类似的问题,但无济于事。
您可以使用 Map
:
my.df[] <- Map(function(x, y) gsub(y, 'R', x), my.df,
substring(names(my.df), nchar(names(my.df)) - 2,nchar(names(my.df)) - 2))
my.df
# col1_A.C col2_A.T col3_C.G
31 RR TT GG
#2 RC RT RG
#3 CC TT RG
使用@thelatemail 的 chartr
技巧与 purrr
中的 imap_dfc
:
purrr::imap_dfc(my.df, ~chartr(substr(.y, nchar(.y)-2, nchar(.y)-2), 'R', .x))
同样可以通过首先将数据从宽格式转换为长格式来实现:
library(tidyverse)
my.df %>%
gather(colx, rowx) %>%
mutate(rowx = str_replace_all(rowx, substring(colx, nchar(colx) - 2, nchar(colx) -
2), "R")) %>%
group_by(colx) %>%
mutate(id = row_number()) %>%
pivot_wider(names_from = colx, values_from = rowx)
我认为您只需要波浪号 ~
,并使用 .fns
而不是 .funs
。
my.df %>%
mutate(
across(
.cols = everything(),
.fns = ~ str_replace_all(
string = ..1,
pattern = str_sub(cur_column(), nchar(cur_column()) - 2, nchar(cur_column()) - 2),
replacement = "R"
)
)
)
我的目标总结
我有以下数据帧结构:
my.df <-data.frame("col1_A.C"=c("AA","AC","CC"),
"col2_A.T"=c("TT","AT","TT"),
"col3_C.G"=c("GG","CG","CG"))
my.df
# col1_A.C col2_A.T col1_C.G
# 1 AA TT GG
# 2 AC AT CG
# 3 CC TT CG
对于每一列,我想用字符“R”替换与列名的倒数第三个字符匹配的任何字符。
使用上面的数据框,我想得到这个:
my.df2 <- data.frame("col1_A.C"=c("RR","RC","CC"),
"col2_A.T"=c("TT","RT","TT"),
"col3_C.G"=c("GG","RG","RG"))
my.df2
# col1_A.C col2_A.T col1_C.G
# 1 RR TT GG
# 2 RC RT RG
# 3 CC TT RG
例如,在第一列中,列名是 col1_A.C,A 是倒数第三个字符。因此,所有 A 都被替换为 R。
到目前为止我的代码
为了实现这一点,我制作了以下代码
my.df2 <- my.df %>% mutate(across(.cols=everything(),
.funs=str_replace_all(.,
substr(cur_column(),
nchar(cur_column()-2),
nchar(cur_column()-2)
),
"R")
)
)
不幸的是,生成的数据帧 my.df2 看起来与 my.df 完全一样,并且没有字符替换发生了。虽然没有返回错误。
我已经通过以下方式测试了 str_replace_all() 方法,它适用于向量。我想我 missing/not 理解 str_replace_all() 在 mutate(across())[ 中的解释方式=48=]函数。
first.column <- c("CC","CT","CC")
first.column <- str_replace_all(first.column,
substr(colnames(my.df)[1],
nchar(colnames(my.df)[1])-2,
nchar(colnames(my.df)[1])-2
),
"R")
print(first.column)
# [1] "RR" "RT" "RR"
我 运行 不知道什么可能不起作用。我对 R 及其功能的理解不是很透彻,所以如果我遗漏了一些简单的东西,我深表歉意。我也搜索过类似的问题,但无济于事。
您可以使用 Map
:
my.df[] <- Map(function(x, y) gsub(y, 'R', x), my.df,
substring(names(my.df), nchar(names(my.df)) - 2,nchar(names(my.df)) - 2))
my.df
# col1_A.C col2_A.T col3_C.G
31 RR TT GG
#2 RC RT RG
#3 CC TT RG
使用@thelatemail 的 chartr
技巧与 purrr
中的 imap_dfc
:
purrr::imap_dfc(my.df, ~chartr(substr(.y, nchar(.y)-2, nchar(.y)-2), 'R', .x))
同样可以通过首先将数据从宽格式转换为长格式来实现:
library(tidyverse)
my.df %>%
gather(colx, rowx) %>%
mutate(rowx = str_replace_all(rowx, substring(colx, nchar(colx) - 2, nchar(colx) -
2), "R")) %>%
group_by(colx) %>%
mutate(id = row_number()) %>%
pivot_wider(names_from = colx, values_from = rowx)
我认为您只需要波浪号 ~
,并使用 .fns
而不是 .funs
。
my.df %>%
mutate(
across(
.cols = everything(),
.fns = ~ str_replace_all(
string = ..1,
pattern = str_sub(cur_column(), nchar(cur_column()) - 2, nchar(cur_column()) - 2),
replacement = "R"
)
)
)