How to Read Specific Lines of A Large Irregular Data File in R
<p>I work in data management, meaning people give me raw data and I have to format and parse it to get the pieces I need and organize it in a way that makes sense. Currently the data I'm working with is a log file, but I have opened and saved it as a text file. It looks a bit like this:</p>
<blockquote>
<p>M 20160525 09:51:11.822 DOC1: Clearing stale DENIED send to 1864130A.62274 in 13 after 39411ms</p>
<p>D 20160525 09:51:11.824 F798257E GET 10.19.100.24:62274 van8tc - &quot;/pcgc/public/Other/&quot; &quot;*li&quot; Done</p>
<p>M 20160525 09:51:11.825 DOC1: F798257E Transaction has been acknowledged at 15804727</p>
<p>F 20160525 09:51:11.825 F798257E GET 10.19.100.24:62274 van8tc - &quot;/pcgc/public/Other/&quot; &quot;*li&quot; 441 (0,0) &quot;0.10 seconds (36.8 kilobits/sec)&quot;
D 20160525 09:51:11.825 F798257E GET 10.19.100.24:62274 van8tc - &quot;/pcgc/public/Other/&quot; &quot;*li&quot; - &quot;Freeing Package Unit&quot;</p>
</blockquote>
<p>It's quite a large file, and I don't wish to import the entire thing into R mainly because of the amount of space it takes up. Each line has &quot;fields&quot; (what I want to organize and separate) that are designated as the following:</p>
<ol>
<li>F                   -- identifier of the line</li>
<li>20160525            -- date (yyyymmdd)</li>
<li>17:52:38.791        -- timestamp (HH:MM:SS.sss)</li>
<li>F798259D            -- transfer identifier</li>
<li>156.145.15.85:46634 -- IP address and related port</li>
<li>xqixh8sl            -- username</li>
<li>AES                 -- encryption level (could be - (dash))</li>
<li>&quot;/pcgc...fastq.gz&quot;  -- transferred file (in &quot;)</li>
<li>&quot;&quot;                  -- additional string (should be empty &quot;&quot;)</li>
<li>2951144113          -- transferred bytes</li>
<li>(0,0)               -- error</li>
<li>&quot;2289.47 seconds (10.3 megabits/sec)&quot; -- data about the transfer</li>
</ol>
<p>The only lines I need are the ones that start with F and have a (0, 0) error. Here is an example line:</p>
<blockquote>
<p>F 20160525 17:52:38.791 F798259D GET 156.145.15.85:46634 xqixh8sl AES &quot;/pcgc/public/Other/exome/fastq/PCGC0053681_HS_EX__1-02598__v1_FCAD18P7ACXX_L8_p92of93_P1.fastq.gz&quot; &quot;&quot; 2951144113 (0,0) &quot;2289.47 seconds (10.3 megabits/sec)&quot;</p>
</blockquote>
<p>And I would NOT consider a line like this:</p>
<blockquote>
<p>F 20160602 14:15:48.398 F7982D62 GET 156.145.15.85:36773 xqixh8sl AES &quot;/pcgc/public/Other/exome/fastq/PCGC0065109_HS_EX__1-04692__v3_FCAD2HMUACXX_L4_p1of1_P2.fastq.gz&quot; &quot;&quot; 50725464 (4,32) &quot;Remote Application: Session Aborted: Aborted by user interrupt&quot;</p>
</blockquote>
<p>The line above did not have a (0, 0) error, so it would not be considered.</p>
<p>My question is this: since the file is so large, I want to able to parse through it and pick out only the lines I need beforehand. Then, once I import it, I want the best way to organize it neatly. I know that there are a variety of ways to read the file (I have been trying with <code>readLines()</code> and <code>scan()</code>) but I don't know how to write in the conditional statement (the line must start with F, and must have a (0, 0) error).</p>
<p>I have tried a variety of things:</p>
<ol>
<li><p>Used <code>scan()</code> to import the entire file into R as a list.</p>
<p><code>x &lt;- scan(&quot;dataSet.txt&quot;, what = list(lineID = &quot;&quot;, date = &quot;&quot;, timestamp = &quot;&quot;,      transferID = &quot;&quot;, IP = &quot;&quot;, username = &quot;&quot;, encryption = &quot;&quot;, transferredFile = &quot;&quot;, error = &quot;&quot;, data = &quot;&quot;), sep = &quot; &quot;, fill = TRUE, strip.white = TRUE)</code></p>
<p><code>logs &lt;- list(x)</code></p>
<p><code>logs</code></p>
</li>
</ol>
<p>While I liked the numbering and rows, it left out a lot of fields that I needed. This is the output it gave me:</p>
<blockquote>
<p>[9062] &quot;&quot;<br />
[9063] &quot;&quot;<br />
[9064] &quot;&quot;<br />
[9065] &quot;&quot;<br />
[9066] &quot;&quot;<br />
[9067] &quot;&quot;<br />
[9068] &quot;&quot;<br />
[9069] &quot;&quot;<br />
[9070] &quot;&quot;<br />
[9071] &quot;&quot;<br />
[9072] &quot;&quot;<br />
[9073] &quot;Mnr:0&quot;<br />
[9074] &quot;&quot;<br />
[9075] &quot;Mnr:0&quot;<br />
[9076] &quot;&quot;<br />
[9077] &quot;&quot;<br />
[9078] &quot;data&quot;<br />
[9079] &quot;&quot;<br />
[9080] &quot;2,&quot;<br />
[9081] &quot;12,&quot;<br />
[9082] &quot;&quot;<br />
[9083] &quot;&quot;<br />
[9084] &quot;550F919C.60099&quot;</p>
</blockquote>
<ol start="2">
<li>I found as example online of this, so I copied it and tried to use it similarly. However, it did not give me what I desired. If someone could explain how this works, that would also be greatly appreciated. However, the way I used it also imported the entire file.</li>
</ol>
<p><code>&gt; setwd(&quot;/Users/kimm5w/Intern Work&quot;)</code></p>
<p><code>&gt; dataset &lt;- list()</code></p>
<p><code>&gt; con &lt;- file(&quot;dataSet.txt&quot;)</code></p>
<p><code>&gt; open(con)</code></p>
<p><code>&gt; dataset &lt;- grep(&quot;F&quot;, scan(&quot;dataSet.txt&quot;, what = list(lineID = &quot;&quot;, date = &quot;&quot;, timestamp = &quot;&quot;, transferID = &quot;&quot;, IP = &quot;&quot;, username = &quot;&quot;, encryption = &quot;&quot;, transferredFile = &quot;&quot;, error = &quot;&quot;, data = &quot;&quot;), sep = &quot; &quot;, fill = TRUE, strip.white = TRUE), perl = TRUE, value = TRUE)</code></p>
<p><code>&gt; dataset</code></p>
<p>This is the output it gave me, which was not the format I wanted:</p>
<p><code>\&quot;[0]\&quot;, \&quot;\&quot;, \&quot;xqixh8sl:\&quot;, \&quot;\&quot;, \&quot;\&quot;, \&quot;\&quot;, \&quot;\&quot;, \&quot;Mnr:0\&quot;, \&quot;\&quot;, \&quot;Mnr:0\&quot;, \&quot;\&quot;, \&quot;\&quot;, \&quot;data\&quot;, \&quot;\&quot;, \&quot;at\&quot;, \&quot;\&quot;, \&quot;\&quot;, \&quot;\&quot;, \&quot;\&quot;, \&quot;\&quot;, \&quot;\&quot;, \&quot;\&quot;, \&quot;\&quot;, \&quot;\&quot;, \&quot;\&quot;, \&quot;\&quot;, \&quot;\&quot;, \&quot;\&quot;, \&quot;Mnr:0\&quot;, \&quot;\&quot;, \&quot;Mnr:0\&quot;, \&quot;\&quot;, \&quot;\&quot;, \&quot;data\&quot;, \&quot;\&quot;, \&quot;at\&quot;, \&quot;\&quot;, \&quot;\&quot;, \&quot;\&quot;, \&quot;\&quot;, \&quot;\&quot;, \&quot;\&quot;, \&quot;\&quot;, \&quot;\&quot;, \&quot;\&quot;, \&quot;\&quot;, \&quot;\&quot;, \&quot;\&quot;, \&quot;\&quot;, \&quot;Mnr:0\&quot;, \&quot;\&quot;, \&quot;Mnr:0\&quot;, \&quot;\&quot;, \&quot;\&quot;, \&quot;data\&quot;, \&quot;\&quot;, \&quot;550F919C.36474\&quot;, \&quot;\&quot;, \&quot;550F919C.42385\&quot;, \&quot;\&quot;, \&quot;550F919C.49879\&quot;, \&quot;\&quot;, \&quot;550F919C.53923\&quot;, \&quot;\&quot;, \&quot;6,\&quot;, \&quot;18,\&quot;, \&quot;\&quot;, \&quot;550F919C.36773\&quot;, \&quot;\&quot;, \&quot;\&quot;, \&quot;\&quot;, \&quot;\&quot;, \&quot;\&quot;, \&quot;\&quot;, \&quot;\&quot;, \&quot;\&quot;, \&quot;\&quot;, \&quot;\&quot;, \&quot;\&quot;, \&quot;\&quot;, \&quot;\&quot;, \&quot;\&quot;, \&quot;\&quot;, \&quot;\&quot;, \&quot;at\&quot;, \&quot;\&quot;, \&quot;\&quot;, \&quot;\&quot;, \&quot;\&quot;, \&quot;\&quot;, \n\&quot;\&quot;, \&quot;\&quot;, \&quot;550F919C.37525\&quot;, \&quot;\&quot;, \&quot;6,\&quot;, \&quot;18,\&quot;, \&quot;\&quot;)&quot;</code></p>
<p>I'm fairly new at R; I learned Java and though the concepts are similar, the syntax is unfamiliar. If anyone can help me with this, please do! I've been working on this for about a week and can't figure it out. Thank you for your help!</p>
<p><strong>UPDATE</strong></p>
<p>Here's what I've tried so far after going through your suggestions:</p>
<pre><code>    setwd(&quot;/Users/kimm5w/Intern Work&quot;)
    df&lt;-data.frame(readLines(&quot;dataSet.txt&quot;))
    F_dataSet &lt;- grep(&quot;^F.*(0,0)&quot;, &quot;dataSet.txt&quot;)
    F_dataSet

    library(stringr)
    x = 0
    while(x &lt; length(readLines(&quot;dataSet.txt&quot;))){
      line &lt;- readLines(&quot;dataSet.txt&quot;)
      if (str_sub(line, 1, 1) == 'F' &amp; grepl('\\(0\\,0\\)', line)[1]){
        F_data &lt;- c(F_data, line)
        }
    }
    display(F_data)
</code></pre>
<p>For some reason when I try and run it in R, it doesn't display the result. However, it does run without error. My question is if one of these will work. I can't use a for loop because the exact number of lines isn't known. So instead, I tried using a while loop in the second version. The link was helpful, but a bit confusing because I wasn't familiar with the syntax. If someone could explain each section I think it would be easier to understand. On the first attempt, I just tried using grep() to sort out the lines I needed, but I'm not sure if it worked. If anyone can help out from here, that would be very much appreciated. And to those that sent me answers, thank you too. This has helped me a lot, and is the most progress I've made in a while.</p>
<p>Here's another update. It runs fine, but for some reason the while loop does not print anything. F_data does not show up when I try to display it. Could someone point out where the error is?</p>
<pre><code>    setwd(&quot;/Users/kimm5w/Intern Work&quot;)
    F_data &lt;- data.frame
    print(F_data)
    library(stringr)
    x &lt;- length(readLines(&quot;dataSet.txt&quot;))
    print(x)
    while(x != 0)
      {
      line &lt;- readline(&quot;dataSet.txt&quot;)
      print(line)
      if (str_sub(line, 1, 1) == 'F' &amp; grepl('\\(0\\,0\\)', line)[1]){
        F_data &lt;- c(F_data, line)
        print(F_data)
      }
      x &lt;- x + 1
    }
    close(con)
    F_data
</code></pre>