Comment puis-je lire des lignes sélectionnées à partir d'un fichier volumineux à l'aide de la R “readLines de la commande” et de les écrire dans un bloc de données?
Je me suis engagé dans le nettoyage des données. J'ai une fonction qui identifie mal rangées dans un grand fichier d'entrée (trop grand pour être lu d'un seul coup, compte tenu de ma taille de la ram) et renvoie les numéros de ligne de la mauvaise lignes comme un vecteur badRows
. Cette fonction semble fonctionner.
Je suis maintenant en train de lire juste les mauvaises lignes dans un bloc de données, sans succès jusqu'à présent.
Mon approche actuelle consiste à utiliser read.table
sur une connexion ouverte à mon fichier, à l'aide d'un vecteur, le nombre de lignes à sauter entre chaque ligne de lecture. Ce nombre est égal à zéro pour les mauvaises consécutifs lignes.
- Je calculer skipVec
:
(badRowNumbers - c(0, badRowNumbers[1:(length(badRowNumbers-1]))-1
Mais pour le moment je suis juste de remettre ma fonction d'un skipVec
vecteur de tous les zéros.
Si ma logique est correcte, il doit retourner toutes les lignes. Il ne le fait pas. Au lieu de cela, j'obtiens une erreur:
"Erreur de lecture.tableau(con, skip = pass, nrow = 1, header = TRUE, sep =
"") : pas de lignes disponibles dans l'entrée"
Ma fonction actuelle est vaguement basé sur une fonction par Miron Kursa ("mbq"), que j'ai trouvé ici.
Ma question est un peu redondant, mais je suppose que sa fonctionne, donc j'ai cassé quelque sorte. Je suis encore à essayer de comprendre la différence entre l'ouverture d'un fichier et l'ouverture d'une connexion à un fichier, et je soupçonne que le problème est là, quelque part, ou dans mon utilisation de lapply
.
Je suis en cours d'exécution de la R 3.0.1 sous RStudio 0.97.551 sur un grincheux vieux Windows XP SP3 machine avec 3gig de ram. L'Âge de la pierre, je sais.
Voici le code qui génère le message d'erreur ci-dessus:
# Make a small small test data frame, write it to a file, and read it back in
# a row at a time.
testThis.DF <- data.frame(nnn=c(2,3,5), fff=c("aa", "bb", "cc"))
testThis.DF
# This function will work only if the number of bad rows is not too big for memory
write.table(testThis.DF, "testThis.DF")
con<-file("testThis.DF")
open(con)
skipVec <- c(0,0,0)
badRows.DF <- lapply(skipVec, FUN=function(pass){
read.table(con, skip=pass, nrow=1, header=TRUE, sep="") })
close(con)
L'erreur se produit avant la commande fermer. Si je copie le readLines de commande de la lapply et de la fonction et de s'en tenir simplement par lui-même, je reçois toujours le même message d'erreur.
OriginalL'auteur andrewH | 2013-10-06
Vous devez vous connecter pour publier un commentaire.
Si au lieu de courir
read.table
parlapply
il suffit de lancer les premières itérations manuellement, vous verrez ce qui se passe:Parce que
header = TRUE
il n'est pas une ligne qui est lu à chaque itération, mais deux, de sorte que vous arriver de manquer de lignes plus vite que vous ne le pensez, ici, sur la troisième itération:Maintenant, cela peut toujours pas être un moyen très efficace de résoudre votre problème, mais c'est la façon dont vous pouvez corriger votre code actuel:
Quelques indices vers des vitesses plus élevées:
scan
au lieu deread.table
. Lire les données quecharacter
et seulement à la fin, après que vous avez mis vos données dans une matrice de caractère ou de données.image, appliquertype.convert
pour chaque colonne.skipVec
, en boucle sur sonrle
si elle est beaucoup plus courte. De sorte que vous serez en mesure de lire ou de sauter des morceaux de lignes à la fois.Ce code ne fonctionne pas n'est pas très utile pour moi, à moins que vous me dire pourquoi cela ne fonctionne pas. Inattendus de sortie, le message d'erreur? Notez que cela fonctionne avec votre exemple, alors peut-être votre véritable fichier de données d'un format différent de celui que vous nous construire dans cet exemple.
Une connexion est comme un fichier qui est ouverte, de sorte qu'il peut être consulté à plusieurs reprises pour la lecture ou l'écriture. Le raccordement comprend un pointeur à l'endroit où la dernière lecture des données ou écrite. Quand vous ouvrez d'abord le fichier, le fichier de la poignée vers le début du fichier. Après l'utilisation de
read.table(con, skip=0, nrow=1, header=TRUE, sep="")
la première fois, l'en-tête et la première ligne de données de votre dossier sont lus de sorte que le pointeur est maintenant pointant vers le début de la deuxième ligne de données.Cher @flodel Par "ne fonctionne pas", je voulais dire seulement que, comme je l'ai dit, j'ai essayé de l'obtenir pour retourner toutes les lignes comme mauvais. Votre code renvoie le premier et troisième rangées de mon jouet exemple. J'ai passé beaucoup de temps à essayer de comprendre pourquoi tu avais changé mes lignes paramètre, jusqu'à ce que j'ai réalisé que votre code renvoyé la bonne réponse pour la skipRows vous m'avez donné - le paramètre a été mauvais, mais l'algorithme de droit. C'est pourquoi j'ai dit que je pensais que c'était juste une faute de frappe. Si vous êtes d'accord, dites-le ou de modifier le 1 à 0 & je vais légère augmentation de la réponse. Je serais toujours reconnaissante de savoir pourquoi vous avez utilisé d'analyse pour la 1ère ligne.
Je vois maintenant. Ce n'était pas une faute de frappe: j'ai fait changer la valeur de
skipVec
sur le but. Je pensais avoir un mélange de bonnes et de mauvaises lignes a été plus représentative exemple de votre problème plus général: il a aussi montré que mon algorithme a été correctement garder ou de rejeter les lignes. Sinon, siskipVec
ne contient que des zéros, on pourrait dire que vous pouvez simplement exécuterread.table("testThis.DF", header = TRUE)
et fait. Désolé, je n'ai pas été bien clair.OriginalL'auteur flodel