1
$\begingroup$

I have been trying to use the ReadList function to read in a large list of words, characters and numbers. I have a file (student-mat.txt) that contains a line of words, characters and numbers all separated with a space and different records on each line. I have seen an example of this done (from my university) with a different file and they simply use the ReadList function with the addition of Word and Number functions till all there data is read in, such as:

mylist = ReadList["file.txt", {Number, Word, Number, Word, Real, Number, Real, Real}];

With a file file.txt that looks like:

1 orange 2 brown 0.14 147 3.55 1045
1 orange 2 brown 0.14 152 3.33 985
1 orange 2 brown 0.18 159 2.88 1515
1 orange 3 green 0.08 152 3.17 1185
1 orange 4 orange 0.18 174 3.03 1120
1 orange 4 orange 0.12 162 3.1 1260
1 orange 4 orange 0.09 186 3.2 830
1 orange 4 orange 0.18 176 3.38 795
1 orange 4 orange 0.15 162 2.87 1285

Which works. My code and file is a little larger but is a very similar set up:

mylist = ReadList[
f, {Word, Character, Number, Character, Word, Character, Number, 
Number, Word, Word, Word, Word, Number, Number, Number, Word, 
Word, Word, Word, Word, Word, Word, Word, Number, Number, Number, 
Number, Number, Number, Number, Number, Number, Number}];

With a file that looks like:

GP F 18 U GT3 A 4 4 at_home teacher course mother 2 2 0 yes no no no yes yes no no 4 3 4 1 1 3 6 5 6 6
GP F 17 U GT3 T 1 1 at_home other course father 1 2 0 no yes no no no yes yes no 5 3 3 1 1 3 4 5 5 6
GP F 15 U LE3 T 1 1 at_home other other mother 1 2 3 yes no yes no yes yes yes no 4 3 2 2 3 3 10 7 8 10

But when I run the code through Mathematica it returns the error:

ReadList::readn: Invalid real number found when reading from /Users/Cassidy/Documents/Uni/Physics/Year 2/Computational Science/Project 4/student-mat.txt.

To solve this problem I tried to troubleshoot by replacing all the types of variable with the Word variable, like:

mylist = ReadList[
f, {Word, Word, Word, Word, Word, Word, Word, Word, Word, Word, 
Word, Word, Word, Word, Word, Word, Word, Word, Word, Word, Word, 
Word, Word, Word, Word, Word, Word, Word, Word, Word, Word, Word, 
Word}]

And when I do this Mathematica returns the correct list with record breaks in the right place. Although, when I try to change the second type of variable from Word to Character, it pushes the second variable in each record to the right and saves a space " " under the Character specification.

I have tried many things to make this work. As I use a Mac, I tried doing exactly the same process entirely on a different Windows PC and Mathematica returned the same error. I have tried stripping all formatting from the file. I have also used a .CSV version of the file to no success. I am lost as to what to do next. Any help would be appreciated.

Many thanks

$\endgroup$
  • $\begingroup$ So MMA recognized a space as a character, as would be expected. You fixed this with Word instead of Character and got the desired result. What exactly is the problem then? Note it that MMA doesn't distinguish between a character and a string of length one. $\endgroup$ – LLlAMnYP Oct 24 '17 at 11:59
  • $\begingroup$ The problem is I would like to save the values as Word, Character and Number where applicable in the data. Otherwise, I have to add extra steps to retrieve this data which should be unnecessary and will make my code inefficient. MMA is, for some reason, not recognising any other variable type than Word - which is almost useless for my needs. $\endgroup$ – Cassidy Hazel Oct 24 '17 at 12:06
  • $\begingroup$ What about Word and Number? $\endgroup$ – Cassidy Hazel Oct 24 '17 at 13:02
  • $\begingroup$ I see I've missed that you replaced Number with Word too. If you only replace Character with Word,, it still doesn't work? $\endgroup$ – LLlAMnYP Oct 24 '17 at 13:10
  • $\begingroup$ doesn't Import[ .. , "Table"] do what you want? $\endgroup$ – george2079 Oct 24 '17 at 21:19
1
$\begingroup$

The following works for me.

strm = StringToStream[
  "GP F 18 U GT3 A 4 4 at_home teacher course mother 2 2 0 yes no no 
no yes yes no no 4 3 4 1 1 3 6 5 6 6
  GP F 17 U GT3 T 1 1 at_home other course father 1 2 0 no yes no no 
no yes yes no 5 3 3 1 1 3 4 5 5 6
  GP F 15 U LE3 T 1 1 at_home other other mother 1 2 3 yes no yes no 
yes yes yes no 4 3 2 2 3 3 10 7 8 10"]

ReadList[strm, {Word, Word, Number, Word, Word, Word, Number, Number, 
  Word, Word, Word, Word, Number, Number, Number, Word, Word, Word, 
  Word, Word, Word, Word, Word, Number, Number, Number, Number, 
  Number, Number, Number, Number, Number, Number}]
{{"GP", "F", 18, "U", "GT3", "A", 4, 4, "at_home", "teacher", 
  "course", "mother", 2, 2, 0, "yes", "no", "no", "no", "yes", "yes", 
  "no", "no", 4, 3, 4, 1, 1, 3, 6, 5, 6, 6}, {"GP", "F", 17, "U", 
  "GT3", "T", 1, 1, "at_home", "other", "course", "father", 1, 2, 0, 
  "no", "yes", "no", "no", "no", "yes", "yes", "no", 5, 3, 3, 1, 1, 3,
   4, 5, 5, 6}, {"GP", "F", 15, "U", "LE3", "T", 1, 1, "at_home", 
  "other", "other", "mother", 1, 2, 3, "yes", "no", "yes", "no", 
  "yes", "yes", "yes", "no", 4, 3, 2, 2, 3, 3, 10, 7, 8, 10}}

Note how words and characters are wrapped in quotes (treated as strings), while numbers are interpreted correctly as representations of integers and read in as so.

I have copied your initial attempt with ReadList but replaced all Character with Word. Be aware that upon failure to read in a record the position in the stream may be in some awkward place, such as between F and 18. Then when you start experimenting with different second arguments for ReadList it tries to read from some place other than the beginning of the file and stumbles. Closing and reopening the fixes things and should let the second command (ReadList) run correctly.

| improve this answer | |
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.