无法使用 tm for R 中的 DataframeSource 从数据框中获取元数据
Can't get metadata from dataframe using DataframeSource in tm for R
我有一个包含以下变量的数据框:
doc_id text URL author date forum
当我运行
samplecorpus <- Corpus(DataframeSource(sampledataframe))
文档说我应该得到一个语料库,其中包含作为文档级元数据添加的所有额外变量。
https://rdrr.io/rforge/tm/man/DataframeSource.html
http://finzi.psych.upenn.edu/R/library/tm/html/DataframeSource.html
相反,我得到了一个语料库,其中包含所有按正确顺序排列的正确文档,但它们的所有元数据都是空白的。我需要此元数据来过滤文档以供将来分析。
其他人也问过类似的问题,但一直没有人回答...
In tm version a readTabular() replacement tm package DataframeSource () ignores my other columns as metadata
有人知道如何解决这个问题吗?
谢谢!
tm
的文档对此进行了解释(请参阅 ??tm::DublicCore
)。来自文档:
A corpus has two types of metadata. Corpus metadata ("corpus") contains corpus specific metadata in form of tag-value pairs. Document level metadata ("indexed") contains document specific metadata but is stored in the corpus as a data frame. Document level metadata is typically used for semantic reasons (e.g., classifications of documents form an own entity due to some high-level information like the range of possible values) or for performance reasons (single access instead of extracting metadata of each document). The latter can be seen as a from of indexing, hence the name "indexed". Document metadata ("local") are tag-value pairs directly stored locally at the individual documents.
DataframeSource
仅自动分配 语料库 元数据*。例如,查看以下打印内容:
library(tm)
data <- data.frame(doc_id = c(234345345, 1299),
text = c("The Prince and the Pauper",
"Little Women"),
author = c('Mark Twain', 'Louisa May Alcott'),
date = c(1881, 1868),
stringsAsFactors = FALSE)
samplecorpus <- Corpus(DataframeSource(data))
meta(samplecorpus)
# Or even
meta(samplecorpus[1], tag = 'author')
为了在文档级别分配元数据,您可以使用 meta
更改标签。奇怪的是,这仅在您使用 VCorpus
时有效。所以稍微改变上面的内容,你可以这样做:
samplecorpus <- VCorpus(DataframeSource(data))
# Can now set document metadata tags
meta(samplecorpus[[1]], tag = 'author') <- 'Mark Twain'
*编辑:
进一步考虑(并回应 OP 的评论),我同意该文档不是对包观察到的行为的完全准确描述。上面引用的文档指的是三个级别(语料库、索引文档级别和本地文档级别),在我的示例中,它们分别对应于 samplecorpus
、samplecorpus[1]
和 samplecorpus[[1]]
。如果这是正确的,那么元数据 是 由 DataframeSource
在承诺的级别分配(如果有点含糊,因为他们从未指定 which文件级)。然而,文档还声称索引文档级别存储为数据框,本地存储为标签值对,但两者都存储为列表。令人困惑。我只能得出结论,这是包实现中的错误或文档中的错误。
除非联系软件包作者来解决这个问题(这不是一个坏主意),否则我会提出以下解决方法:
samplecorpus <- VCorpus(DataframeSource(data))
transfer_metadata <- function(x, i, tag){
return(meta(x[i], tag=tag)[[tag]])
}
tags <- colnames(data)
tags <- tags[! tags %in% c('doc_id', 'text')]
for(i in 1:length(samplecorpus)){
for (tag in tags){
meta(samplecorpus[[i]], tag=tag) <- transfer_metadata(samplecorpus, i=i, tag=tag)
}
}
您必须检查所有内容是否正确加载。我制作了一个示例文档 data.frame 以便您了解它是如何工作的。我使用了与您相同的列名并添加了 1 个额外的(标签)。基于这个例子,你可能会检查你是否在某处有问题。
docs <- data.frame(doc_id = c("doc_1", "doc_2"),
text = c("This is a text.", "This another one."),
url = c("",
""),
author = c("Emi", "Emi"),
date = as.Date(c("2018-09-20", "2018-09-21")),
forum = c("Whosebug", "Whosebug"),
tags = c("r", "tm"),
stringsAsFactors = T)
# use Corpus or VCorpus
my_corpus <- Corpus(DataframeSource(docs))
meta(my_corpus)
url author date
1 Emi 2018-09-20
2 Emi 2018-09-21
forum tags
1 Whosebug r
2 Whosebug tm
my_index <- meta(my_corpus, "tags") == "r"
inspect(my_corpus[my_index])
<<SimpleCorpus>>
Metadata: corpus specific: 1, document level (indexed): 5
Content: documents: 1
doc_1
This is a text.
现在请注意元数据的处理方式有所不同。如果您这样做 str(my_corpus)
,您将看到以下内容:
List of 2
$ doc_1:List of 2
..$ content: chr "This is a text."
..$ meta :List of 7
.. ..$ author : chr(0)
.. ..$ datetimestamp: POSIXlt[1:1], format: "2018-09-21 08:55:44"
.. ..$ description : chr(0)
.. ..$ heading : chr(0)
.. ..$ id : chr "doc_1"
.. ..$ language : chr "en"
.. ..$ origin : chr(0)
.. ..- attr(*, "class")= chr "TextDocumentMeta"
..- attr(*, "class")= chr [1:2] "PlainTextDocument" "TextDocument"
$ doc_2:List of 2
......
您在此处看到的元信息来自 meta(my_corpus, type = "local")
。使用DataframeSource加载的元数据是索引类型,meta(my_corpus, type = "indexed")
the vignette 的第 5 页对于阅读和试验以查看 meta 和 DublinCore 的所有不同选项很重要。
我有一个包含以下变量的数据框:
doc_id text URL author date forum
当我运行
samplecorpus <- Corpus(DataframeSource(sampledataframe))
文档说我应该得到一个语料库,其中包含作为文档级元数据添加的所有额外变量。 https://rdrr.io/rforge/tm/man/DataframeSource.html http://finzi.psych.upenn.edu/R/library/tm/html/DataframeSource.html
相反,我得到了一个语料库,其中包含所有按正确顺序排列的正确文档,但它们的所有元数据都是空白的。我需要此元数据来过滤文档以供将来分析。
其他人也问过类似的问题,但一直没有人回答... In tm version a readTabular() replacement tm package DataframeSource () ignores my other columns as metadata
有人知道如何解决这个问题吗?
谢谢!
tm
的文档对此进行了解释(请参阅 ??tm::DublicCore
)。来自文档:
A corpus has two types of metadata. Corpus metadata ("corpus") contains corpus specific metadata in form of tag-value pairs. Document level metadata ("indexed") contains document specific metadata but is stored in the corpus as a data frame. Document level metadata is typically used for semantic reasons (e.g., classifications of documents form an own entity due to some high-level information like the range of possible values) or for performance reasons (single access instead of extracting metadata of each document). The latter can be seen as a from of indexing, hence the name "indexed". Document metadata ("local") are tag-value pairs directly stored locally at the individual documents.
DataframeSource
仅自动分配 语料库 元数据*。例如,查看以下打印内容:
library(tm)
data <- data.frame(doc_id = c(234345345, 1299),
text = c("The Prince and the Pauper",
"Little Women"),
author = c('Mark Twain', 'Louisa May Alcott'),
date = c(1881, 1868),
stringsAsFactors = FALSE)
samplecorpus <- Corpus(DataframeSource(data))
meta(samplecorpus)
# Or even
meta(samplecorpus[1], tag = 'author')
为了在文档级别分配元数据,您可以使用 meta
更改标签。奇怪的是,这仅在您使用 VCorpus
时有效。所以稍微改变上面的内容,你可以这样做:
samplecorpus <- VCorpus(DataframeSource(data))
# Can now set document metadata tags
meta(samplecorpus[[1]], tag = 'author') <- 'Mark Twain'
*编辑:
进一步考虑(并回应 OP 的评论),我同意该文档不是对包观察到的行为的完全准确描述。上面引用的文档指的是三个级别(语料库、索引文档级别和本地文档级别),在我的示例中,它们分别对应于 samplecorpus
、samplecorpus[1]
和 samplecorpus[[1]]
。如果这是正确的,那么元数据 是 由 DataframeSource
在承诺的级别分配(如果有点含糊,因为他们从未指定 which文件级)。然而,文档还声称索引文档级别存储为数据框,本地存储为标签值对,但两者都存储为列表。令人困惑。我只能得出结论,这是包实现中的错误或文档中的错误。
除非联系软件包作者来解决这个问题(这不是一个坏主意),否则我会提出以下解决方法:
samplecorpus <- VCorpus(DataframeSource(data))
transfer_metadata <- function(x, i, tag){
return(meta(x[i], tag=tag)[[tag]])
}
tags <- colnames(data)
tags <- tags[! tags %in% c('doc_id', 'text')]
for(i in 1:length(samplecorpus)){
for (tag in tags){
meta(samplecorpus[[i]], tag=tag) <- transfer_metadata(samplecorpus, i=i, tag=tag)
}
}
您必须检查所有内容是否正确加载。我制作了一个示例文档 data.frame 以便您了解它是如何工作的。我使用了与您相同的列名并添加了 1 个额外的(标签)。基于这个例子,你可能会检查你是否在某处有问题。
docs <- data.frame(doc_id = c("doc_1", "doc_2"),
text = c("This is a text.", "This another one."),
url = c("",
""),
author = c("Emi", "Emi"),
date = as.Date(c("2018-09-20", "2018-09-21")),
forum = c("Whosebug", "Whosebug"),
tags = c("r", "tm"),
stringsAsFactors = T)
# use Corpus or VCorpus
my_corpus <- Corpus(DataframeSource(docs))
meta(my_corpus)
url author date
1 Emi 2018-09-20
2 Emi 2018-09-21
forum tags
1 Whosebug r
2 Whosebug tm
my_index <- meta(my_corpus, "tags") == "r"
inspect(my_corpus[my_index])
<<SimpleCorpus>>
Metadata: corpus specific: 1, document level (indexed): 5
Content: documents: 1
doc_1
This is a text.
现在请注意元数据的处理方式有所不同。如果您这样做 str(my_corpus)
,您将看到以下内容:
List of 2
$ doc_1:List of 2
..$ content: chr "This is a text."
..$ meta :List of 7
.. ..$ author : chr(0)
.. ..$ datetimestamp: POSIXlt[1:1], format: "2018-09-21 08:55:44"
.. ..$ description : chr(0)
.. ..$ heading : chr(0)
.. ..$ id : chr "doc_1"
.. ..$ language : chr "en"
.. ..$ origin : chr(0)
.. ..- attr(*, "class")= chr "TextDocumentMeta"
..- attr(*, "class")= chr [1:2] "PlainTextDocument" "TextDocument"
$ doc_2:List of 2
......
您在此处看到的元信息来自 meta(my_corpus, type = "local")
。使用DataframeSource加载的元数据是索引类型,meta(my_corpus, type = "indexed")
the vignette 的第 5 页对于阅读和试验以查看 meta 和 DublinCore 的所有不同选项很重要。