如何替换 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 中多个文件的特定字符串值?的主要内容,如果未能解决你的问题,请参考以下文章