如何替换 R 中多个文件的特定字符串值?

Posted

技术标签:

【中文标题】如何替换 R 中多个文件的特定字符串值?【英文标题】:How to replace specific string values for several files in R? 【发布时间】:2021-12-29 14:58:49 【问题描述】:

我有 50 个文件(每个文件有 100 万到 200 万行),所有文件都有一个 variant_id 列,我想对其进行更改 - 这些文件都有这样的布局:

variant_id                    ...
chr1_665098_G_A_b38           ...
chr2_665097_C_T_b38           ...
chr3_665094_A_GG_b38          ...
chr10_23458_TTTCAAG_C_b38     ...

我想将variant_id 列编辑为:

variant_id
1:665098
2:665097
3:665094
10:23458

我正在尝试通过以下方式同时对我的所有文件进行此更改:

#Read in all files
temp = list.files(pattern="*.txt")
for (i in 1:length(temp)) assign(temp[i], fread(temp[i]))

#Edit variant_id strings for every dataset in environment
my_func <- function(x) 
  x <- x %>%
    select(variant_id, pval_nominal) %>%
    mutate(variant_id = sub("^([^-]*-[^-]*).*", "\\1", variant_id))


e <- .GlobalEnv
nms <- ls(pattern = ".txt$", envir = e)
for(nm in nms) e[[nm]] <- my_func(e[[nm]])

我被困在mutate(variant_id = sub("^([^-]*-[^-]*).*", "\\1", variant_id)) - 不知道如何最好地使用sub 来实现我需要的所有更改,删除chr,第一个_ 成为:,然后拥有所有删除第二个数值后的字符。我怎样才能得到这个工作?有没有更好的功能可以尝试?任何帮助表示赞赏。

输入示例数据:

df <- structure(list(variant_id = c("chr1_665098_G_A_b38", "chr2_665097_C_T_b38", 
"chr3_665094_A_GG_b38", "chr10_23458_TTTCAAG_C_b38\xca")), row.names = c(NA, 
-4L), class = c("data.table", "data.frame"))

【问题讨论】:

【参考方案1】:

我们可以使用sub来捕获字符并替换为捕获组的反向引用

library(data.table)
df[, variant_id := sub("chr(\\d+)_(\\d+)_.*", "\\1:\\2", variant_id)]

-输出

> df
   variant_id
1:   1:665098
2:   2:665097
3:   3:665094
4:   10:23458

如果是多个文件,则读取list中的文件,并保存在list

lst1 <- lapply(temp, function(x) fread(x)[,
    variant_id := sub("chr(\\d+)_(\\d+)_.*", "\\1:\\2", variant_id)][])

【讨论】:

【参考方案2】:

这是您的情况的完全可重现的示例。

这里的目标不仅是向您展示另一种可能的正则表达式解决方案,而且是另一种设置代码的方法。

我注意到您在函数中选择了 2 个特定列,因此我在代码中添加了该选项。

# reproducible example
df <- data.frame(variant_id = c("chr1_665098_G_A_b38", "chr2_665097_C_T_b38", 
                                "chr3_665094_A_GG_b38", "chr10_23458_TTTCAAG_C_b38\xca"),
                 pval_nominal = c(0.005,0.01),
                 filler = letters[1:2])
folder <- tempdir()
write.csv(df, file.path(folder, "test1.txt"))
write.csv(df, file.path(folder, "test2.txt"))
# library
library(data.table)

# read all files: use full paths! you'll avoid a lot of issues
temp <- list.files(folder, pattern = "*.txt", full.names = TRUE)

# read files with lappply and make a list of them!
l <- lapply(temp, fread, sep = ",")

# select columns and modify variant_id
# if you use data.table you generally want to stick with it and not to mix it with dplyr and viceversa (but that depends on you)
l <- lapply(l, function(d) d[,.(variant_id = sub("^\\D+(\\d+)_(\\d+).*", "\\1:\\2", variant_id), pval_nominal)])
l
#> [[1]]
#>    variant_id pval_nominal
#> 1:   1:665098        0.005
#> 2:   2:665097        0.010
#> 3:   3:665094        0.005
#> 4:   10:23458        0.010
#> 
#> [[2]]
#>    variant_id pval_nominal
#> 1:   1:665098        0.005
#> 2:   2:665097        0.010
#> 3:   3:665094        0.005
#> 4:   10:23458        0.010

由reprex package 创建于 2021-11-18 (v2.0.0)

【讨论】:

以上是关于如何替换 R 中多个文件的特定字符串值?的主要内容,如果未能解决你的问题,请参考以下文章

用多个新字符串替换文件中特定位置的单个字符串

Perl:在多个文本文件中查找和替换特定字符串

如何在 R 中删除包含特定字符串的行?

用一个值替换 Pandas 系列中的多个子字符串

如何使用 Flutter 在 Firestore 中删除具有特定值的多个文档

如何在fluentd中用特定字符串替换键值字符串