在lapply函数中,R下标与stringer和grep越界



我的目标是在匹配特定模式后,从几个文件夹中的多个文本文件中提取固定长度(8位(的字符串。

我花了一整天的时间来构建一个lapply函数,这样子目录中的所有文件(最多20个(都可以自动处理。不过我失败了。工作流程的代码是可执行的,但由于我对R的了解不足,仅限于一个文件。

在有数字的行之间,每个文件有一个字符串,每个字符串都不同,我想提取这些字符串。字符串提取的输出应存储在文件夹中。

字符串具有以下结构:String[one or two digits]_[eight digits]。例如,String1_20220101或String12_20220108。我想提取下划线后面的部分。

文本文件的结构是这样的,每个文件超过10000行。

文件1:示例

X1  X2
1 1000 100
2 1050 100
3 1100 100
4 1150 100
5 1200 100
6 String1_20220101
7 1250 100
8 1300 100
9 1350 100
10 1400 100
x1 <- list(c(seq(1000,1400, by=50)))
[1] 1000 1050 1100 1150 1200 1250 1300 1350 1400
x2 <- list(c(rep(100, 9)))
[1] 100 100 100 100 100 100 100 100 100

文件2:

x1     x2
1 2000  200
2 3000  200
3 4000  200
4 5000  200
5 6000  200
6 7000  200
7 String12_20220108
8 8000  200
9 9000  200
10 10000 200

x1 <- list(c(seq(1000,10000,by=1000)))
[1]  1000  2000  3000  4000  5000  6000  7000  8000  9000 10000
x2 <- list(c(rep(200, 9)))
[1] 200 200 200 200 200 200 200 200 200

这些文件位于编号文件夹中,其名称来源于文件夹编号,属于一个观察。

我的文件夹1:代码

library(stringr)
Folderno1 <- list.files(path = "path/to/file/1/",
pattern = "*.txt",
full.names = TRUE)
FUN <- function(Folder1) {
folder_input <- readLines(Folderno1)
string <- grep("String[0-9]_", folder_input, value = TRUE)
output <- capture.output(as.numeric(str_extract_all(string, "(?<=[0-9]{1,2}_)[0-9]+")[[1]]))
write(output, file="/pathtofile/String1.tex")
}
lapply(Folderno1, FUN)
Error in str_extract_all(string, "(?<=[0-9]{1,2}_)[0-9]+")[[1]] : 
subscript out of bounds

出现上述错误消息。文件String1.tex可以被覆盖,尽管有错误消息,但只有一个结果:

[1] 20220101

带调试的重新运行显示:

function (x) 
.Internal(withVisible(x))

你能告诉我如何成功地更改工作流程,以便处理每个文件吗?我无法理解。

谢谢。

在函数中,每次都覆盖同一个文件(write(output, file="/pathtofile/String1.tex")(。可能,您希望为每个.txt文件创建一个新的.tex文件。

从错误消息中,我认为有些文件没有我们正在寻找的模式(String[0-9]_(。String[0-9]_不能与String12_20220108一样使用2位数。我已将其更改为使用String[0-9]+_。为了更安全起见,我还添加了一个if条件来检查输出的长度。

试试这个解决方案-

Folderno1 <- list.files(path = "path/to/file/1/",
pattern = "*.txt",
full.names = TRUE)
FUN <- function(Folder1) {
#Read the file
folder_input <- readLines(Folder1)
#Extract the line which has "String" in it
string <- grep("String[0-9]+_", folder_input, value = TRUE)
#If such line exists
if(length(string)) {
#Remove everything till underscore to get 8-digit number
output <- sub('.*_', '', string)
#Remove everything after underscore to get "String1", "String12"
out <- sub('_.*', '', string)
#Write the output
write(output, file= paste0('/pathtofile/', out, '.tex'))
}
}
lapply(Folderno1, FUN)

最新更新