Organisation de cette question:
I. Background
II. The Problem/Question
III. Steps Taken to Make this Question Good
IV. Update: the output of head(x.path) and dput(x.path)
I. Contexte
Je personnalise/adapte le code de classification des e-mails du livre O'Reilly "Machine Learning for Hackers" (Chapitre 3). Ce code et les données qui l'accompagnent peuvent être trouvés ici: https://github.com/johnmyleswhite/ML_for_Hackers/tree/master/03-Classification
II. Le problème/la question
L'une des fonctions principales de ce code est appelée get.msg()
. La fonction d'origine est
get.msg <- function(path)
{
con <- file(path, open = "rt", encoding = "latin1")
text <- readLines(con)
# The message always begins after the first full line break
msg <- text[seq(which(text == "")[1] + 1, length(text), 1)]
close(con)
return(paste(msg, collapse = "\n"))
}
Cependant, mes données sont différentes de plusieurs façons, donc je dois les modifier un peu. Mes données sont lues plus tôt à partir d'une base de données relationnelle, donc je n'ai pas besoin de lire et de nettoyer un fichier texte. Au lieu de cela, mes données de corps d'e-mail sont la 18e colonne d'une trame de données, que nous pouvons appeler x
. Voici ma version de get.msg()
:
get.msg <- function(path) {
bodyvector <- path[!(is.na(path[,18]) | path[,18]==""), ]
return(paste(bodyvector))
}
À l'origine, je l'appelais x$email
Et cela a fonctionné à travers la plupart du code, mais dans une étape ultérieure, la fonction get.msg()
a été utilisée sur x.path
, Où x.path
pointait sur x
et était utilisé dans une autre fonction en combinaison avec la fonction paste()
, selon les auteurs de l'exemple de code:
z.spam <- sapply(spam.docs, function(p) count.Word(paste(x.path,p,sep = ""), "keyword"))
Ici, la fonction count.Word()
est une fonction contenant get.msg()
. Ainsi, la fonction paste()
causait des problèmes car elle faisait apparemment que x.path
Était considéré comme un tableau atomique et donnait l'erreur que $ ne pouvait pas être utilisé avec un tableau atomique. Conformément à une ancienne Q&A StackOverflow, j'ai changé la façon dont j'ai référé la colonne à path[,18]
(Qui est évalué comme x.path[,18]
Et est donc identique à x[,18]
).
Ensuite, j'ai fait quelques vérifications pour m'assurer que x.path[,18]
Avait les mêmes informations que x.path$email
, Ce qu'il a fait. Cependant, lorsque j'essaie d'exécuter le code, j'obtiens un message d'erreur sur get.msg(x.path)
, qui est:
Error in path[,18] : incorrect number of dimensions.
J'ai essayé path[,'email']
, Puis path[18,]
, Puis juste path
par lui-même et les trois ont conduit à la même erreur. J'ai essayé path[[1]][[18]]
Et cela m'a donné une erreur d'indice hors limites.
Des pensées?
III. Mesures prises pour que cette question soit bonne
Pour éviter d'ennuyer quelqu'un et d'obtenir des votes négatifs, j'ai confirmé que le sujet était pertinent pour StackOverflow et je pense qu'il pourrait être pertinent pour d'autres personnes confrontées à ce problème ou à des problèmes de programmation similaires à l'avenir. J'ai également passé près d'une heure à rechercher ce problème en ligne et à essayer des choses dans R pour le résoudre.
Il y avait beaucoup de références à ce message d'erreur, mais les causes semblaient être très diverses et totalement indépendantes (telles que des problèmes de réseau, etc.). Enfin, j'ai passé beaucoup de temps à éditer cette question pour essayer de la rendre lisible et correctement formatée (j'espère que j'ai bien fait, je sais que c'est beaucoup d'informations).
IV. La sortie de head()
et dput()
Certains d'entre vous, extrêmement utiles, ont demandé à voir la sortie de head(x.path)
ou dput(x.path)
. Cela ne me dérange pas, sauf que ce sont les données confidentielles de la société et que je serai sans emploi et poursuivi si je les publie. ;-)
Je l'ai collé ici et remplacé les vraies informations par de fausses informations. J'espère que ça va. J'ai essayé d'utiliser dput()
au début et je peux le faire si vous le souhaitez, mais c'était vraiment une quantité écrasante de données. Voici head(x.path)
:
> head(x.path)
[1] "c(\"Z12e3317e4b1jZbbajZ9Zdd6\", \"Z12e3317e4b1jZbbajZ99124\", \"Z12e331Ze4b1jZbbajZ996dd\", \"Z12e3319e4b1jZbbajZ9acb6\", \"Z12e3319e4b1jZbbajZ9ad3b\", \"Z12e3319e4b1jZbbajZ9adjd\", \"Z12e3319e4b1jZbbajZ9aebZ\", \"Z12e3319e4b1jZbbajZ9aj23\", \"Z12e3319e4b1jZbbajZ9b22b\", \"Z12e3319e4b1jZbbajZ9b42a\", \"Z12e3319e4b1jZbbajZ9b49a\", \"Z12e331ae4b1jZbbajZ9bZ11\", \"Z12e331ae4b1jZbbajZ9bZZ4\", \"Z12e331ae4b1jZbbajZ9c237\", \"Z12e331ae4b1jZbbajZ9c2e4\", \"Z12e331ae4b1jZbbajZ9c3bZ\", \"Z12e331ae4b1jZbbajZ9c3cZ\", \"Z12e331ae4b1jZbbajZ9cZ31\", \n\"Z12e331be4b1jZbbajZ9cddd\", \"Z12e331be4b1jZbbajZ9cja6\", \"Z12e331ce4b1jZbbajZ9da1j\", \"Z12e331de4b1jZbbajZ9e649\", \"Z12e331de4b1jZbbajZ9j669\", \"Z12e331de4b1jZbbajZ9jZZZ\", \"Z12e331ee4b1jZbbajZ9j944\", \"Z12e331ee4b1jZbbajZ9jcZa\", \"Z12e331ee4b1jZbbajZ9jd4c\", \"Z12e331ee4b1jZbbajZa11e2\", \"Z12e331ee4b1jZbbajZa1291\", \"Z12e331ee4b1jZbbajZa1344\", \"Z12e3311e4b1jZbbajZa1j73\", \"Z12e3311e4b1jZbbajZa1131\", \"Z12e3311e4b1jZbbajZa11Z6\", \"Z12e3311e4b1jZbbajZa124c\", \"Z12e3311e4b1jZbbajZa1Zbc\", \"Z12e3311e4b1jZbbajZa19a9\", \n\"Z12e3311e4b1jZbbajZa1ac2\", \"Z12e3311e4b1jZbbajZa1b79\", \"Z12e3311e4b1jZbbajZa1db2\", \"Z12e3311e4b1jZbbajZa1ejb\", \"Z12e3312e4b1jZbbajZa2333\", \"Z12e3312e4b1jZbbajZa23aZ\", \"Z12e3312e4b1jZbbajZa24bb\", \"Z12e3312e4b1jZbbajZa2Z79\", \"Z12e3312e4b1jZbbajZa2Zea\", \"Z12e3312e4b1jZbbajZa2ba9\", \"Z12e3312e4b1jZbbajZa2cZa\", \"Z12e3313e4b1jZbbajZa3bc1\", \"Z12e3313e4b1jZbbajZa3ca9\", \"Z12e3313e4b1jZbbajZa3e71\", \"Z12e3ajbe4b1j66Zbcja4eZc\", \"Z12e3ajbe4b1j66Zbcja4ja4\", \"Z12e3c79e4b1j66ZbcjaZc36\", \"Z12e3e1ce4b1j66Zbcja64bd\", \n\"Z12e4117e4b1j66Zbcja6Zj1\", \"Z12e41bae4b1j66Zbcja734Z\", \"Z12e4226e4b1j66Zbcja7b13\", \"Z12e4226e4b1j66Zbcja7cbZ\", \"Z12e4ajee4b1j66Zbcjaa916\", \"Z12e4e61e4b1j66Zbcjab1c2\", \"Z12e4e61e4b1j66Zbcjab2da\", \"Z12eZ226e4b1j66ZbcjacZea\", \"Z12e6141e4b1j66Zbcjb19Z9\", \"Z12e6141e4b1j66Zbcjb19jd\", \"Z12e61Z9e4b1j66Zbcjb1acb\", \"Z12e61Z9e4b1j66Zbcjb1acj\", \"Z12j9713e4b1j66Zbcjc34db\", \"Z12j9713e4b1j66Zbcjc3ZZa\", \"Z12j9713e4b1j66Zbcjc3Za7\", \"Z12j9713e4b1j66Zbcjc3Zd2\", \"Z12j9713e4b1j66Zbcjc36c2\", \"Z12j973ce4b1j66Zbcjc396b\"\n)"
[2] "c(\"Something\", \"Something\", \"Something\", \"Something\", \"Something\", \"Something\", \"Something\", \"Something\", \"Something\", \"Something\", \"Something\", \"Something\", \"Something\", \"Something\", \"Something\", \"Something\", \"Something\", \"Something\", \"Something\", \"Something\", \"Something\", \"Something\", \"Something\", \"Something\", \"Something\", \"Something\", \"Something\", \"Something\", \"Something\", \"Something\", \"Something\", \"Something\", \"Something\", \"Something\", \"Something\", \"Something\", \"Something\", \"Something\", \"Something\", \"Something\", \"Something\", \"Something\", \"Something\", \"Something\", \"Something\", \"Something\", \"Something\", \"Something\", \"Something\", \"Something\", \"Something\", \"Something\", \"Something\", \"Something\", \"Something\", \"Something\", \n\"Something\", \"Something\", \"Something\", \"Something\", \"Something\", \"Something\", \"Something\", \"Something\", \"Something\", \"Something\", \"Something\", \"Something\", \"Something\", \"Something\", \"Something\", \"Something\")"
[3] "c(61Z7, 674Z, Z462, 692, Z26, 1121, 1213, 1317, 21ZZ, 2Z9Z, 2711, 3612, 3717, 4774, 4Z93, Z117, Z113, Z197, Z77Z, 61Z3, Z16Z, 11771, 12923, 13374, 13Z93, 14277, 1446Z, 1Z3ZZ, 1ZZ16, 1Z993, 164Z2, 16664, 1711Z, 171Z6, 1Z6ZZ, 1Z921, 19211, 193ZZ, 19931, 21117, 21164, 21177, 21371, 21Z61, 21673, 22ZZ7, 23137, 2ZZ44, 26166, 26Z1Z, 173Z6, 17661, 21Z74, 23119, 232ZZ, 249Z3, 2ZZ31, 261Z9, 31211, 33414, 336Z6, 37941, 1743, 1Z61, 216Z, 2171, 1ZZ3, 2119, 21Z4, 2129, 2334, 2ZZZ)"
[4] "c(\"Booty\", \"Booty\", \"Booty\", \"Booty\", \"Booty\", \"Booty\", \"Booty\", \"Booty\", \"Booty\", \"Booty\", \"Booty\", \"Booty\", \"Booty\", \"Booty\", \"Booty\", \"Booty\", \"Booty\", \"Booty\", \"Booty\", \"Booty\", \"Booty\", \"Booty\", \"Booty\", \"Booty\", \"Booty\", \"Booty\", \"Booty\", \"Booty\", \"Booty\", \"Booty\", \"Booty\", \"Booty\", \"Booty\", \"Booty\", \"Booty\", \"Booty\", \"Booty\", \"Booty\", \"Booty\", \"Booty\", \"Booty\", \"Booty\", \"Booty\", \"Booty\", \"Booty\", \"Booty\", \n\"Booty\", \"Booty\", \"Booty\", \"Booty\", \"Booty\", \"Booty\", \"Booty\", \"Booty\", \"Booty\", \"Booty\", \"Booty\", \"Booty\", \"Booty\", \"Booty\", \"Booty\", \"Booty\", \"Booty\", \"Booty\", \"Booty\", \"Booty\", \"Booty\", \"Booty\", \"Booty\", \"Booty\", \"Booty\", \"Booty\")"
[5] "c(Z6, 93Z, 1314, 3, 4, Z, 6, 7, 9, 11, 11, 13, 14, 2Z, 26, 27, 2Z, 29, 33, 34, ZZ, Z3, 122, 12Z, 133, 139, 142, 147, 1Z2, 1Z3, 16Z, 169, 171, 171, 219, 221, 221, 222, 22Z, 226, 244, 246, 247, 24Z, 249, 2637, 264, 2Z9, 292, 296, 49, Z1, 76, 93, 9Z, 112, 111, 114, 1Z7, 211, 214, 263, 6, 7, 11, 11, 11, 11, 12, 13, 14, 1Z)"
[6] "c(3Z11, 3Z11, 3Z11, 691Z, 691Z, 691Z, 691Z, 691Z, 691Z, 691Z, 691Z, 691Z, 691Z, 691Z, 691Z, 691Z, 691Z, 691Z, 691Z, 691Z, 691Z, 691Z, 691Z, 691Z, 691Z, 691Z, 691Z, 691Z, 691Z, 691Z, 691Z, 691Z, 691Z, 691Z, 691Z, 691Z, 691Z, 691Z, 691Z, 691Z, 691Z, 691Z, 691Z, 691Z, 691Z, 691Z, 691Z, 691Z, 691Z, 691Z, Z664, Z664, Z664, Z664, Z664, Z664, Z664, Z664, Z664, Z664, Z664, Z664, 66Z1, 66Z1, 66Z1, 66Z1, 4ZZ4, 4ZZ4, 4ZZ4, 4ZZ4, 4ZZ4, 4ZZ4)"
Si cela devait vous en montrer plus, vous verriez des corps de message pour [18].
Votre exemple est un peu complexe à exécuter, mais j'ai eu cette erreur plusieurs fois et le problème a toujours été dû en fin de compte au comportement par défaut de la fonction d'extraction (c'est-à-dire []) en contraignant au plus petit nombre possible de dimensions. Comme BondedDust le fait remarquer, si vous extrayez une seule colonne d'un bloc de données, vous ne pouvez plus sélectionner des sous-ensembles du bloc avec la même syntaxe, car vous n'avez plus de bloc de données.
Ces problèmes disparaissent fréquemment si, dans une opération dans laquelle vous réduisez peut-être la trame de données à une seule colonne, vous définissez le paramètre drop = FALSE dans l'opération d'extraction. Je suggère que vous examiniez attentivement non seulement la ligne où l'erreur est générée, mais également toutes les lignes précédentes dans lesquelles l'opération "[]" est utilisée sur la trame de données du problème. Consultez l'aide de la méthode de trame de données pour la fonction d'extraction, "extract.data.frame" pense que le problème est probablement que lorsque vous sous-définissez le bloc de données sur une seule colonne, il est contraint à une seule dimension et ne peut plus être indexé par numéro de colonne ou numéro de ligne.
Cela pourrait mériter d'être un commentaire, mais cela ne conviendrait pas et je suis prêt à supprimer si cela est justifié. Vous dites
"Donc, la fonction de collage causait des problèmes car elle faisait apparemment considérer x.path comme un tableau atomique, et donnait l'erreur que $ ne pouvait pas être utilisé avec un tableau atomique. fait référence à la colonne du chemin [ 18] (qui est évalué comme x.path [ 18] et est donc identique à x [ 18]). "
Si x.path est un tableau atomique, vous ne pouvez pas utiliser x.path[ , 18]
mais plutôt utiliser x.path[18]
.
Vous pouvez inspecter x.path avec str (x.path) et votre sortie suggère qu'il s'agit bien d'un vecteur de caractères. Dans R, seuls les objets à deux dimensions (matrices et data.frames) peuvent être référencés avec des références d'objet [ n].