1
$\begingroup$

I'm new to mathematica and stack exchange, so any help would be appreciated. I want to plot a bunch of data from text files that contain a lot of extraneous data. I have a hundred files with different serial numbers. In each file, there are a series of "T" values (they are the same across all 100 files) and a series of "tts" values (they vary between serial numbers).

This is the format of the files: enter image description here

Here is a pastebin link to an example of my data

I want to average all of the "tts" values that correspond to a given "T" value from all 100 files and generate a plot of this data for all given "T" values.

files=FileNames["*.txt","/dir"]

raw=Import[#,"Data"]&/@files

TList=Position[raw,"T="]

I'm trying to create a list of all "T" values based on the string that precedes all of these values. (I'll create a separate list of all "tts" values so I can average them later)

I am able to create a list of points using Position, however, it is not selecting the right numbers to put in to the list despite the string I'm using being uniform for all "T" values through all the files. It seems it is taking some of the right numbers and appending wrong ones as well.

Any tips or a better approach?

$\endgroup$
  • 2
    $\begingroup$ It would be good if you could post at least one "block" of your data here, verbatim, because whether those are tabs or spaces etc. matters. Also it allows people to try out their solutions. Welcome to Mathematica.Stackexchange! $\endgroup$ – C. E. Jun 21 '15 at 3:20
  • $\begingroup$ Thanks for the response! Oops, sorry I've updated it. $\endgroup$ – Neil Mehta Jun 21 '15 at 3:32
1
$\begingroup$

Here's how I'd do it...

Grab all the file names you want from a directory:

files = FileNames["*.txt", "directory_here"];

Then apply a function to grab those values...

grabdata[filepath_] := Module[{text = Import[filepath, "Table"]},
 Thread[Cases[text, {#, num_} :> ToExpression[num]] & /@ {"T=", 
 "tts="}]]

grabdata/@files

{{1, 3.39718691228346348}, {6, 7.080849480488796814}}

(I only typed in the first two data points, since file wasn't made available...) Importing as a Table will handle spaces or tabs in the above function.

Plotting will be left to the O.P.

$\endgroup$
  • $\begingroup$ Thanks so much! What I have now is a list of lists of points. I now want to find the mean of all the "tts" values that correspond to a single "T" value. Based on the way the list is formatted I don't seen an easy way to take the mean of these values and create a smaller list of points that doesn't have duplicate "T" values. Any help would be appreciated. $\endgroup$ – Neil Mehta Jun 21 '15 at 4:03
  • 1
    $\begingroup$ @NeilMehta Join the lists together and then look up GatherBy and take the mean of the second elements $\endgroup$ – kale Jun 21 '15 at 4:16
1
$\begingroup$

Here is a way to do what you want in one go. If you put your file names in a list named e.g. files, then the following gives you a list of lists, where each sub-list gives you the "T" value paired with the average of the corresponding "tts" value:

getData[files_?(VectorQ[#, StringQ] &)] := 
 Module[{str = ReadList[#, String] & /@ files // Flatten},
  StringCases[str, {"T=" ~~ Whitespace ~~ x : NumberString :> x, 
        "tts=" ~~ Whitespace ~~ y : NumberString :> y}] // Flatten // 
     ToExpression // Partition[#, 2] & // Mean /@ GatherBy[#, First] &]

Use as follows:

files = {"plotquestion.txt", "plotquestion2.txt"}; (* your list of files *)
getData @ files
{{1, 3.39718691228346348}, {6, 7.0808494804886796814}, {11, 11.284589165821861556}, 
{16, 16.076246833359153499}, {21, 21.021095199714729063}, {26, 26.02973617361801217}, 
{31, 31.01489863629146981}, {36, 36.00115571060923969}, {41, 40.98893755580333220}, 
{46, 46.00661183261264853}, {51, 50.99972558544307333}, {56, 55.99353601051467422},
{61, 60.98787419533059762}, {66, 65.98262589634859410}, {71, 70.97771079668514460}, 
{76, 75.97307148394530429}, {81, 80.99376174387640504}, {86, 85.99102897956072411},
{91, 90.98844550010794308}, {96, 95.98598897958160592}}

Here, both files contain the same data, hence it looks like nothing was done. You can then pass the data to ListPlot or ListLinePlot for plotting.

$\endgroup$
  • $\begingroup$ Thanks for your advice. I tried your method and I'm not getting any output for some of the commands and then when I go to ListPlot the data, Mathematica tells me that there is no data i.e. it returns NULL $\endgroup$ – Neil Mehta Jun 21 '15 at 5:45
  • $\begingroup$ @NeilMehta, I don't understand, it works just fine. Note that you have to include the full path of the filenames in files and they must be a list of Strings $\endgroup$ – RunnyKine Jun 21 '15 at 5:54

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.