web-dev-qa-db-fra.com

R-Project aucune méthode applicable pour 'méta' appliqué à un objet de classe "caractère"

J'essaie d'exécuter ce code (Ubuntu 12.04, R 3.1.1)

# Load requisite packages
library(tm)
library(ggplot2)
library(lsa)

# Place Enron email snippets into a single vector.
text <- c(
  "To Mr. Ken Lay, I’m writing to urge you to donate the millions of dollars you made from selling Enron stock before the company declared bankruptcy.",
  "while you netted well over a $100 million, many of Enron's employees were financially devastated when the company declared bankruptcy and their retirement plans were wiped out",
  "you sold $101 million worth of Enron stock while aggressively urging the company’s employees to keep buying it",
  "This is a reminder of Enron’s Email retention policy. The Email retention policy provides as follows . . .",
  "Furthermore, it is against policy to store Email outside of your Outlook Mailbox and/or your Public Folders. Please do not copy Email onto floppy disks, Zip disks, CDs or the network.",
  "Based on our receipt of various subpoenas, we will be preserving your past and future email. Please be prudent in the circulation of email relating to your work and activities.",
  "We have recognized over $550 million of fair value gains on stocks via our swaps with Raptor.",
  "The Raptor accounting treatment looks questionable. a. Enron booked a $500 million gain from equity derivatives from a related party.",
  "In the third quarter we have a $250 million problem with Raptor 3 if we don’t “enhance” the capital structure of Raptor 3 to commit more ENE shares.")
view <- factor(rep(c("view 1", "view 2", "view 3"), each = 3))
df <- data.frame(text, view, stringsAsFactors = FALSE)

# Prepare mini-Enron corpus
corpus <- Corpus(VectorSource(df$text))
corpus <- tm_map(corpus, tolower)
corpus <- tm_map(corpus, removePunctuation)
corpus <- tm_map(corpus, function(x) removeWords(x, stopwords("english")))
corpus <- tm_map(corpus, stemDocument, language = "english")
corpus # check corpus

# Mini-Enron corpus with 9 text documents

# Compute a term-document matrix that contains occurrance of terms in each email
# Compute distance between pairs of documents and scale the multidimentional semantic space (MDS) onto two dimensions
td.mat <- as.matrix(TermDocumentMatrix(corpus))
dist.mat <- dist(t(as.matrix(td.mat)))
dist.mat  # check distance matrix

# Compute distance between pairs of documents and scale the multidimentional semantic space onto two dimensions
fit <- cmdscale(dist.mat, eig = TRUE, k = 2)
points <- data.frame(x = fit$points[, 1], y = fit$points[, 2])
ggplot(points, aes(x = x, y = y)) + geom_point(data = points, aes(x = x, y = y, color = df$view)) + geom_text(data = points, aes(x = x, y = y - 0.2, label = row.names(df)))

Cependant, quand je le lance, je reçois cette erreur (dans la ligne td.mat <- as.matrix(TermDocumentMatrix(corpus))):

Error in UseMethod("meta", x) : 
  no applicable method for 'meta' applied to an object of class "character"
In addition: Warning message:
In mclapply(unname(content(x)), termFreq, control) :
  all scheduled cores encountered errors in user code

Je ne sais pas quoi regarder - tous les modules chargés. 

31
user990137

La dernière version de tm (0.60) l'a rendu impossible pour que vous puissiez utiliser des fonctions avec tm_map qui ne fonctionnent plus avec des valeurs de caractère simples. Le problème est donc votre étape tolower puisque ce n'est pas une transformation "canonique" (voir getTransformations()). Il suffit de le remplacer par

corpus <- tm_map(corpus, content_transformer(tolower))

Le wrapper de fonction content_transformer convertira tout le type de données correct dans le corpus. Vous pouvez utiliser content_transformer avec toute fonction destinée à manipuler des vecteurs de caractères afin qu'elle fonctionne dans un pipeline tm_map.

88
MrFlick

Ceci est un peu vieux, mais juste pour des recherches ultérieures sur Google: il existe une solution alternative. Après corpus <- tm_map(corpus, tolower), vous pouvez utiliser corpus <- tm_map(corpus, PlainTextDocument) pour le replacer dans le type de données approprié.

29
Paul Gowder

J'ai eu le même problème et finalement je suis arrivé à une solution:

Il semble que les informations meta de l’objet corpus soient corrompues après l’application de transformations.

Ce que j'ai fait, c'est simplement créer à nouveau le corpus à la fin du processus, une fois qu'il était complètement prêt. Devant surmonter d’autres problèmes, j’ai également écrit une boucle afin de copier le texte dans mon cadre de données:

a<- list()
for (i in seq_along(corpus)) {
    a[i] <- gettext(corpus[[i]][[1]]) #Do not use $content here!
}

df$text <- unlist(a) 
corpus <- Corpus(VectorSource(df$text)) #This action restores the corpus.
1
Gonzalo Sanchez

L'ordre des opérations sur le texte est important. Vous devez supprimer les mots vides avant de supprimer la ponctuation.

J'utilise ce qui suit pour préparer le texte. Mon texte est contenu dans cleanData $ LikeMost.

Parfois, en fonction de la source, vous avez d’abord besoin des éléments suivants:

textData$LikeMost <- iconv(textData$LikeMost, to = "utf-8")

Certains mots vides sont importants, vous pouvez donc créer un ensemble révisé.

#create revised stopwords list
newWords <- stopwords("english")
keep <- c("no", "more", "not", "can't", "cannot", "isn't", "aren't", "wasn't",
          "weren't", "hasn't", "haven't", "hadn't", "doesn't", "don't", "didn't", "won't")


newWords <- newWords [! newWords %in% keep]

Ensuite, vous pouvez exécuter vos fonctions tm:

like <- Corpus(VectorSource(cleanData$LikeMost))
like <- tm_map(like,PlainTextDocument)
like <- tm_map(like, removeWords, newWords)
like <- tm_map(like, removePunctuation)
like <- tm_map(like, removeNumbers)
like <- tm_map(like, stripWhitespace)
0
Bryan Butler