2
$\begingroup$

I have a TXT data file (file.txt) which is formatted like so:

Column A (foo)       Column B             Column C                 
1.315116193802095950 6.564596662766380986 1.000428132834134232
...

Note that there are no tabs (all spaces), but all of the data is exactly the same column width in characters. Import["file.txt"] just spits back the text as is (super useful, thanks Mathematica!). Import["file.txt","Data"] will split the data line by line, but it's still just raw text within each line.

What would be great was an option that was present in good ole' Excel, which is to split the file at defined character widths. How do I get Mathematica to do this?

$\endgroup$
6
  • 5
    $\begingroup$ "Import["file.txt"] just spits back the text as is (super useful, thanks Mathematica!). " - incredible, unacceptable! $\endgroup$
    – Kuba
    Aug 16, 2016 at 7:25
  • 2
    $\begingroup$ p.s. try Import["test.txt", "Table"] $\endgroup$
    – Kuba
    Aug 16, 2016 at 7:28
  • 1
    $\begingroup$ Ah, "Table" seems to work for the numeric data, thanks! But it seems to mess up the header... everything gets broken up by whitespace... anyway, that's not a huge problem $\endgroup$ Aug 16, 2016 at 7:35
  • $\begingroup$ You can customize Read and friends but it is probably easier to fix the first line. $\endgroup$
    – Kuba
    Aug 16, 2016 at 7:37
  • $\begingroup$ These Q&A's appear to be of use here: (6433), (30784), (44229), (50718), (51004), (3890), (17841) $\endgroup$
    – Mr.Wizard
    Aug 16, 2016 at 8:13

2 Answers 2

1
$\begingroup$

What would be great was an option that was present in good ole' Excel, which is to split the file at defined character widths. How do I get Mathematica to do this?

In general you need StringTake which accepts a list of ranges as the second argument:

file = "Column A (foo)       Column B             Column C                 
  1.315116193802095950 6.564596662766380986 1.000428132834134232";
lines = StringSplit[file, "\n"];

data = StringTake[lines, {{1, 20}, {22, 41}, {43, 62}}]
Grid[data, Frame -> All]
{{"Column A (foo)      ", "Column B            ", "Column C            "},     
 {"1.315116193802095950", "6.564596662766380986", "1.000428132834134232"}}

output

You can convert strings representing numbers into actual numbers using NumberString and ToExpression:

Replace[data, 
 s_String /; StringMatchQ[StringTrim[s], NumberString] :> ToExpression[s], {-1}]
{{"Column A (foo)      ", "Column B            ", "Column C            "},
 {1.31511619380209595`18.118964125523707, 6.564596662766380986`18.817208047635546, 
 1.000428132834134232`18.00018589593615}} 
$\endgroup$
0
$\begingroup$

Description

In order to avoid overcomplecating the problem at hand. I'd recommend to do some of the work partially e.g extracting headers. Below example demonstrated how to extract numberical data from the imported file and combine it with manually extracted headers into a table structure.

Example

row = "column (foo) column b column c 1.351 6.56 1.0005"

headers = {"column1", "column2", "column3"};
data = StringCases[row, x : NumberString :> ToExpression[x]];

Grid[{headers, data}]

Output

example

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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