如何根据 R 中的位置向量替换字符串向量中的字符?

How to replace characters in a string vector based on a position vector in R?

举个例子:

set.seed(123)
library(stringi)
df<-data.frame(p=sprintf("%s", stri_rand_strings(11, 11, '[A-Z]')), 
               n=sample(1:10, 11, 1),
               s=sprintf("%s", stri_rand_strings(11, 1, '[A-Z]')))
df
             p  n s
1  GPCMCEHPTEW  3 X
2  STDJRNJGBGX  8 P
3  VTEDZLMEPHF  6 L
4  RHVCVLTRLQA  4 Y
5  FSFVIRYDDRL  7 S
6  VZBLSCZGBRU 10 K
7  JJHCJENNYIM  8 A
8  CWKTELUBVHJ  4 O
9  IANRXAZHYRL 10 M
10 VBTJVNHUCVH  9 W
11 TZCWUKIFOXN  6 V

我想要创建一个新列 new_p,其中 p 中位置 n 的字符被 s 替换。因此第一个 df$new_p[1] 应该是 GPXMCEHPTEW.

一个选项是substring

for(i in seq_len(nrow(df)))  substring(df$p[i], df$n[i], df$n[i]) <- df$s[i]


df
#             p  n s
#1  GPXMCEHPTEW  3 X
#2  STDJRNJPBGX  8 P
#3  VTEDZLMEPHF  6 L
#4  RHVYVLTRLQA  4 Y
#5  FSFVIRSDDRL  7 S
#6  VZBLSCZGBKU 10 K
#7  JJHCJENAYIM  8 A
#8  CWKOELUBVHJ  4 O
#9  IANRXAZHYML 10 M
#10 VBTJVNHUWVH  9 W
#11 TZCWUVIFOXN  6 V

我们也可以利用rawToChar/charToRaw

df$p <- mapply(function(x, y, z) rawToChar(replace(charToRaw(x), y, 
         charToRaw(z))), df$p, df$n, df$s)

数据

df <- structure(list(p = c("GPCMCEHPTEW", "STDJRNJGBGX", "VTEDZLMEPHF", 
"RHVCVLTRLQA", "FSFVIRYDDRL", "VZBLSCZGBRU", "JJHCJENNYIM", "CWKTELUBVHJ", 
"IANRXAZHYRL", "VBTJVNHUCVH", "TZCWUKIFOXN"), n = c(3L, 8L, 6L, 
4L, 7L, 10L, 8L, 4L, 10L, 9L, 6L), s = c("X", "P", "L", "Y", 
"S", "K", "A", "O", "M", "W", "V")), class = "data.frame",
row.names = c("1", 
"2", "3", "4", "5", "6", "7", "8", "9", "10", "11"))

的另一个选项:

library(dplyr)

df %>% 
  rowwise() %>% 
  mutate(p_new = gsub(sprintf(paste0("^(.{",n-1,"}).(.*)")), 
                      sprintf(paste0("\1",s,"\2")), 
                                     p))

#>    p               n s     p_new      
#>    <chr>       <int> <chr> <chr>      
#>  1 GPCMCEHPTEW     3 X     GPXMCEHPTEW
#>  2 STDJRNJGBGX     8 P     STDJRNJPBGX
#>  3 VTEDZLMEPHF     6 L     VTEDZLMEPHF
#>  4 RHVCVLTRLQA     4 Y     RHVYVLTRLQA
#>  5 FSFVIRYDDRL     7 S     FSFVIRSDDRL
#>  6 VZBLSCZGBRU    10 K     VZBLSCZGBKU
#>  7 JJHCJENNYIM     8 A     JJHCJENAYIM
#>  8 CWKTELUBVHJ     4 O     CWKOELUBVHJ
#>  9 IANRXAZHYRL    10 M     IANRXAZHYML
#> 10 VBTJVNHUCVH     9 W     VBTJVNHUWVH
#> 11 TZCWUKIFOXN     6 V     TZCWUVIFOXN