跟进on a question I only posted minutes ago,我需要提出另一个问题。上一个问题没有注意到我还必须查看每个文件的内容。换句话说,我必须遍历目录中的所有文件,和通过每个文件的每一行。
每个文件名都是这样的。
airbag.WS-U-E-A.lst
.
是分隔符,.lst
是扩展名(可读为文本)。
每个文件包含每行数据,例如
/home/nobackup/SONAR/COMPACT/WR-U-E-A/WR-U-E-A0000075.data.ids.xml: <sentence>ja voor den airbag op te pompen eh :p</sentence>
/home/nobackup/SONAR/COMPACT/WR-U-E-A/WR-U-E-A0000129.data.ids.xml: <sentence>Dobby , als ze valt heeft ze dan wel al ne airbag hee</sentence>
我想要做的是,在R中创建一个包含所有文件数据的新数据集。理想情况下它看起来像这样:
ID | filename | word | component | left-context | right-context
----------------------------------------------------------------------------------------------------------------
1 airbag.WS-U-E-A.lst airbag WS-U-E-A ja voor den op te pompen eh :p
2 airbag.WS-U-E-A.lst airbag WS-U-E-A Dobby , als ze valt heeft ze dan wel al ne hee
ID
只是行的id,可以像这样完成:
row.names <- "id"
filename
是文件的名称(显然),which I can do like so:
files <- list.files(pattern="*.lst", full.names=T, recursive=FALSE)
d <- data.frame(fileName = unname(sapply(files, basename)))
然后,我可以从文件名中删除word
和component
d$word <- gsub("\\..+", "", d$fileName, perl=TRUE)
d$component <- gsub("^[^.]+.", "", d$fileName, perl=TRUE)
d$component <- gsub(".lst$", "", d$component, perl=TRUE)
现在出现了我尚未想到的困难部分......
我上面写的所有命令都可以通过 循环文件并获取文件名来完成。但是,正如我所说,每个文件包含多个句子,我需要剖析并放在不同的行上。见上面的例子。你会看到文件名,单词和组件是相同的 - 但左右上下文却不相同。那是因为它们是两个不同的句子,在同一个文件中。
使用两个文件的例子可能会让我的问题更加清晰。
adapter.WR-P-P-F.lst
/home/nobackup/SONAR/COMPACT/WR-P-P-F/WR-P-P-F0000026.data.ids.xml: <sentence>Een aanpassingseenheid ( adapter ) , aangebracht in een behuizing voornamelijk bestaande uit in- en uitvoereenheden , een koppeleenheid , een geheugeneenheid , een besturingseenheid ( met actieve en passieve elementen en monolitische geïntegreerde schakelingen ) en een elektrische voedingseenheid . ></sentence>
/home/nobackup/SONAR/COMPACT/WR-P-P-F/WR-P-P-F0000026.data.ids.xml: <sentence>ID="1">Het toestel ( adapter ) draagt zorg voor de overbrenging van gegevens , met een snelheid van 10 Mbps ( megabits per seconde ) , tussen meerdere automatische gegevensverwerkende machines in een digitaal netwerk . " ></sentence>
/home/nobackup/SONAR/COMPACT/WR-P-P-F/WR-P-P-F0000034.data.ids.xml: <sentence>Overwegende dat deze sensoren niet zijn ontworpen op de installatie van een gepantserde kabel ; dat de mogelijkheid moet worden geboden dat de gepantserde kabel niet verplicht wordt gesteld voor de aansluiting tussen de sensor en de adapter , maar alleen van de adapter naar het controleapparaat ; dat het bijgevolg noodzakelijk is de verordening dienovereenkomstig te wijzigen ;</sentence>
airbag.WS-U-E-A.lst
/home/nobackup/SONAR/COMPACT/WR-U-E-A/WR-U-E-A0000075.data.ids.xml: <sentence>ja voor den airbag op te pompen eh :p</sentence>
/home/nobackup/SONAR/COMPACT/WR-U-E-A/WR-U-E-A0000129.data.ids.xml: <sentence>Dobby , als ze valt heeft ze dan wel al ne airbag hee</sentence>
如果这些是我目录中唯一的两个文件,我的R命令将执行以下操作:
输出看起来像这样
ID | filename | word | component | left-context | right-context
----------------------------------------------------------------------------------------------------------------
1 adapter.WR-P-P-F.lst adapter WR-P-P-F Een aanpassingseenheid ( ) , aangebracht in een behuizing voornamelijk bestaande uit in- en uitvoere[...]
2 adapter.WR-P-P-F.lst adapter WR-P-P-F ID="1">Het toestel ( ) draagt zorg voor de overbrenging van gegevens [...]
3 adapter.WR-P-P-F.lst adapter WR-P-P-F [...] tussen de sensor en de naar het controleapparaat ; [...]
4 airbag.WS-U-E-A.lst airbag WS-U-E-A ja voor den op te pompen eh :p
5 airbag.WS-U-E-A.lst airbag WS-U-E-A Dobby , als ze valt heeft ze dan wel al ne hee
(为了简洁起见我遗漏了一些内容,用 [...] 表示)
我理解这似乎是一个很大的问题,但基本上我需要的是一种循环文件本身的方法,并将每行的行提取到一个新行,同时将有关文件本身的信息放在单独的列中(在同一行)。从行中提取文本是我应该能够自己完成的。例如,如果我能得到这样的东西,它会给我带来很长的路要走:
ID | filename | word | component | sentence
----------------------------------------------------------------------------------------------------------------
1 adapter.WR-P-P-F.lst adapter WR-P-P-F /home/nobackup/SONAR/COMPACT/WR-P-P-F/WR-P-P-F0000026.data.ids.xml: <sentence>Een aanpassingseenheid ( adapter ) , aangebracht in een behuizing voornamelijk bestaande uit in- en uitvoereenheden , een koppeleenheid , een geheugeneenheid , een besturingseenheid ( met actieve en passieve elementen en monolitische geïntegreerde schakelingen ) en een elektrische voedingseenheid . ></sentence>
2 adapter.WR-P-P-F.lst adapter WR-P-P-F /home/nobackup/SONAR/COMPACT/WR-P-P-F/WR-P-P-F0000026.data.ids.xml: <sentence>ID="1">Het toestel ( adapter ) draagt zorg voor de overbrenging van gegevens , met een snelheid van 10 Mbps ( megabits per seconde ) , tussen meerdere automatische gegevensverwerkende machines in een digitaal netwerk . " ></sentence>
3 adapter.WR-P-P-F.lst adapter WR-P-P-F /home/nobackup/SONAR/COMPACT/WR-P-P-F/WR-P-P-F0000034.data.ids.xml: <sentence>Overwegende dat deze sensoren niet zijn ontworpen op de installatie van een gepantserde kabel ; dat de mogelijkheid moet worden geboden dat de gepantserde kabel niet verplicht wordt gesteld voor de aansluiting tussen de sensor en de adapter , maar alleen van de adapter naar het controleapparaat ; dat het bijgevolg noodzakelijk is de verordening dienovereenkomstig te wijzigen ;</sentence>
4 airbag.WS-U-E-A.lst airbag WS-U-E-A /home/nobackup/SONAR/COMPACT/WR-U-E-A/WR-U-E-A0000075.data.ids.xml: <sentence>ja voor den airbag op te pompen eh :p</sentence>
5 airbag.WS-U-E-A.lst airbag WS-U-E-A /home/nobackup/SONAR/COMPACT/WR-U-E-A/WR-U-E-A0000129.data.ids.xml: <sentence>Dobby , als ze valt heeft ze dan wel al ne airbag hee</sentence>
我希望我很清楚我想说的是什么。如果没有随意问。
答案 0 :(得分:0)
创建两个data.frames并合并它们
# what you have so far (file-level data.frame)
files <- list.files(pattern="*.lst", full.names=T, recursive=FALSE)
d <- data.frame(fileName = unname(sapply(files, basename)))
d$word <- gsub("\\..+", "", d$fileName, perl=TRUE)
d$component <- gsub("^[^.]+.", "", d$fileName, perl=TRUE)
d$component <- gsub(".lst$", "", d$component, perl=TRUE)
# new data.frame containing contents of files
e <- do.call(rbind, lapply(files, function(x) {
# create two-column data.frame for each file
## first column is fileName
## second column is data from each file
data.frame(fileName = x, sentence = readLines(x), stringsAsFactors = FALSE)
}))
# the above returns a data.frame `e` containing all file records
# pull out the sentence (probably better ways to do this)
e$sentence <- sapply(strsplit(e$sentence, ".xml: ", fixed = TRUE), `[`, 2)
e$sentence <- gsub("<sentence>", "", e$sentence, fixed = TRUE)
e$sentence <- gsub("</sentence>", "", e$sentence, fixed = TRUE)
# merge `d` and `e` by the common column name `fileName`
out <- merge(d, e, by = "fileName", all = TRUE)
# extract your two "context" variables by splitting the sentence variable by `word`
contexts <- strsplit(out$sentence, out$word)
## this is the left-context (everything to the left of the word)
out$`left-context` <- sapply(contexts, `[`, 1)
## this is the right-context (everything to the right of the word)
out$`right-context` <- sapply(contexts, `[`, 2)
答案 1 :(得分:0)
#set工作目录,如(setwd函数)所示,并手动将所有文件移动到一个目录中,因此分析很好,干净。您必须决定将所有文件保存在目录中的位置。下面,我向您展示了我将所有文件保存在“test”目录中。
setwd("C:/Users/username/Desktop/test") #windows
setwd("/home/username/Desktop/test") #linux
files <- list.files()
df2 <- data.frame(matrix(nrow = 1, ncol = 5), stringsAsFactors = FALSE)
colnames(df2) <- c("filename", "word", "component", "left_context", "right_context")
for(i in files){
word = sub("([a-z]+)(.)([A-Z-]+)(.*)", "\\1", i)
component = sub("([a-z]+)(.)([A-Z-]+)(.*)", "\\3", i)
list1 <- scan(i, sep = ">", what = list("character", "character"))
context = unlist(lapply(list1[[2]], function(x) gsub('</sentence', '', x) ))
for(j in 1:length(context)){
left_context = strsplit(context[j], word)[[1]][1]
right_context = strsplit(context[j], word)[[1]][2]
df1 <- data.frame(filename = i,
word = word,
component = component,
left_context = left_context,
right_context = right_context,
stringsAsFactors = FALSE)
df2 <- rbind(df2, df1)
}
}
df2 <- df2[2:nrow(df2),]
df2 <- cbind(data.frame(ID = 1:nrow(df2), stringsAsFactors = FALSE), df2)
View(df2)
输出:
print(df2)
ID filename word component left_context right_context
1 adapter.WR-P-P-F.lst.txt adapter WR-P-P-F Een aanpassingseenheid ( ) , aangebracht in een behuizing voornamelijk bestaande uit in- en uitvoereenheden , een koppeleenheid , een geheugeneenheid , een besturingseenheid ( met actieve en passieve elementen en monolitische geïntegreerde schakelingen ) en een elektrische voedingseenheid . >
2 adapter.WR-P-P-F.lst.txt adapter WR-P-P-F ID="1">Het toestel ( ) draagt zorg voor de overbrenging van gegevens , met een snelheid van 10 Mbps ( megabits per seconde ) , tussen meerdere automatische gegevensverwerkende machines in een digitaal netwerk . " >
3 adapter.WR-P-P-F.lst.txt adapter WR-P-P-F Overwegende dat deze sensoren niet zijn ontworpen op de installatie van een gepantserde kabel ; dat de mogelijkheid moet worden geboden dat de gepantserde kabel niet verplicht wordt gesteld voor de aansluiting tussen de sensor en de , maar alleen van de
4 airbag.WS-U-E-A.lst.txt airbag WS-U-E-A ja voor den op te pompen eh :p
5 airbag.WS-U-E-A.lst.txt airbag WS-U-E-A Dobby , als ze valt heeft ze dan wel al ne hee
答案 2 :(得分:-1)
您可以使用readLines
从文件中提取数据。在您的情况下,您可以使用嵌套循环来构建数据 - 一个循环遍历文件,并在其中,每行一个循环。
例如,我在~/test
目录中设置了一些文件:
$ ls ~/test
file1.txt file2.txt
文件看起来像这样:
$ ls | xargs cat
I am line 1 from file1.
I am line 2 from file1.
I am line 1 from file2.
I am line 2 from file2.
现在我可以遍历它们并获取文件名和内容 - 我没有做任何正则表达式或处理这些信息,因为你已经表明你可以自己这样做。这仅仅是为了说明如何使用两个循环将文件名和文件内容中的信息添加到同一行:
dir <- '~/test'
df <- data.frame(filename=c(), row.index=c(), row.contents=c())
for (file in list.files(dir)) {
filename = paste0(dir, '/', file)
i <- 1
for (line in readLines(filename)) {
df <- rbind(df, data.frame(filename=filename, row.index=i, row.contents=line))
i <- i + 1
}
}
这导致以下data.frame:
> df
filename row.index row.contents
1 ~/test/file1.txt 1 I am line 1 from file1.
2 ~/test/file1.txt 2 I am line 2 from file1.
3 ~/test/file2.txt 1 I am line 1 from file2.
4 ~/test/file2.txt 2 I am line 2 from file2.
使用这样的rbind可能不是最有效的方法。另一种可能更有效的方法是为最终数据帧中的每一列构建一个向量,然后在完成后从这些向量中创建数据帧。这样可以避免潜在的昂贵的rbind()操作。