2016-03-28 41 views
3

我有一個數據(大數據125000行,〜20 MB),其中某些具有特定字符串的行需要刪除,並且在讀取過程中需要選擇某些列。fread連同grepl

首先,我發現grepl函數無法正常工作,因爲fread使數據成爲一列,這也表示在此question中。

的示例數據可以發現here(由以下@akrun建議)和這樣

頭(sum_data)中的數據的報頭

TRIAL :   1  3331  9091 
    TRIAL :   2 1384786531 278055555 
    2  0.10  0.000E+00 -0.0047 -0.0168 -0.9938 -0.0087 -0.0105 -0.9709  0.0035 0.0079 -0.9754  0.0081 0.0023 0.9997  -0.135324E-09 0.278754E-01 
    2  0.20  0.000E+00 -0.0121 0.0002 -0.9898 -0.0364 -0.0027 -0.9925 -0.0242 -0.0050 -0.9929  0.0029 -0.0023 0.9998  -0.133521E-09 0.425567E-01 
    2  0.30  0.000E+00 0.0193 -0.0068 -0.9884  0.0040 0.0139 -0.9782 -0.0158 0.0150 -0.9814  0.0054 -0.0008 0.9997  -0.134103E-09 0.255356E-01 
    2  0.40  0.000E+00 -0.0157 0.0183 -0.9879 -0.0315 -0.0311 -0.9908 -0.0314 -0.0160 -0.9929  0.0040 0.0010 0.9998  -0.134819E-09 0.257300E-01 
    2  0.50  0.000E+00 -0.0402 0.0300 -0.9832 -0.0093 0.0269 -0.9781 -0.0326 0.0247 -0.9802  0.0044 -0.0010 0.9997  -0.131515E-09 0.440350E-01 

我試圖讀取fread和所使用的數據grepl用於刪除行;

files <-dir(pattern = "*sum.txt",full.names = FALSE) 
library(data.table) 

fread_files <- function(files){ 
sum_data_read <- fread(files,skip=2, sep="\t",) #seperation is tab. 
df_grep <- sum_vgm_read [!grepl("TRI",sum_vgm_read$V1),] # for removing the lines that contain "TRIAL" letter in V1 column. But so far there is no V1 column is recognized!! 

df <- bind_rows(df_grep) #binding rows after removing 
write.table(as.data.table(df),file = gsub("(.*)(\\..*)", "\\1_new\\2", files),row.names = FALSE,col.names = TRUE) 
} 

最後lapply

lapply(files, fread_files) 

當我perfom這一點,只有一個數據行被作爲輸出這點是怎麼回事,但我不知道是什麼創造。 感謝您的幫助!

+0

你只是想讀取文件,刪除行並重寫文件? 或者您是否想要操作數據表或數據框? – cderv

+0

@Titolondon感謝您的詢問。我想寫一個新文件不重寫它們,並希望有列名稱和更快的閱讀處理data.frame,因爲我有很多文件。 – Alexander

+0

您是否嘗試過我的答案?它似乎是做你想做的: 1.讀取文件 2.刪除行 3.在沒有「TRIAL」行的情況下寫入新文件 缺少什麼? 順便說一句,我沒有看到您的示例數據中的colname。你想要什麼名字? – cderv

回答

10

Firstly, I discovered that grepl function does not work properly since fread makes the data as one column indicated also in this question .

但是,這個問題的答案接受說,問題已修復v1.9.6。你正在使用哪個版本?這就是爲什麼我們要求您預先說明版本號,以節省時間回答。

這是一個很好的示例文件,問題很大。

我不會嘗試重新發明輪子,因爲像這樣的操作早已作爲命令行工具實現,您可以直接使用它們與fread一起使用。優點是你不會通過R內存流失,你可以將過濾留給命令工具,並且效率更高。例如,如果將所有行作爲行加載到R中,則這些字符串將緩存到R的全局字符串緩存中(至少暫時)。首先在R之外進行過濾可以節省成本。

我下載了你的偉大文件,並測試了以下工作。

> fread("grep -v TRIAL sum_data.txt") 
     V1 V2 V3  V4  V5  V6  V7  V8  V9  V10  V11  V12 V13  V14 V15   V16  V17 
    1: 2 0.1 0 -0.0047 -0.0168 -0.9938 -0.0087 -0.0105 -0.9709 0.0035 0.0079 -0.9754 0.0081 0.0023 0.9997 -1.35324e-10 0.0278754 
    2: 2 0.2 0 -0.0121 0.0002 -0.9898 -0.0364 -0.0027 -0.9925 -0.0242 -0.0050 -0.9929 0.0029 -0.0023 0.9998 -1.33521e-10 0.0425567 
    3: 2 0.3 0 0.0193 -0.0068 -0.9884 0.0040 0.0139 -0.9782 -0.0158 0.0150 -0.9814 0.0054 -0.0008 0.9997 -1.34103e-10 0.0255356 
    4: 2 0.4 0 -0.0157 0.0183 -0.9879 -0.0315 -0.0311 -0.9908 -0.0314 -0.0160 -0.9929 0.0040 0.0010 0.9998 -1.34819e-10 0.0257300 
    5: 2 0.5 0 -0.0402 0.0300 -0.9832 -0.0093 0.0269 -0.9781 -0.0326 0.0247 -0.9802 0.0044 -0.0010 0.9997 -1.31515e-10 0.0440350 
    ---              

124247: 250 49.5 0 -0.0040 0.0141 0.9802 -0.0152 0.0203 -0.9877 -0.0015 0.-0.9901 0.0069 0.0003 0.9997 -1.30220e-10 0.0213215 
124248: 250 49.6 0 -0.0006 0.0284 0.9819 0.0021 0.0248 -0.9920 0.0264 0.0408 -0.9919 0.0028 -0.0028 0.9997 -1.30295e-10 0.0284142 
124249: 250 49.7 0 0.0378 0.0305 0.9779 -0.0261 0.0232 -0.9897 -0.0236 0.0137 -0.9928 0.0102 -0.0023 0.9997 -1.29890e-10 0.0410760 
124250: 250 49.8 0 0.0569 -0.0203 0.9800 -0.0028 -0.0009 -0.9906 -0.0139 -0.0169 -0.9918 0.0039 -0.0017 0.9997 -1.31555e-10 0.0513482 
124251: 250 49.9 0 0.0234 -0.0358 0.9840 -0.0340 0.0114 -0.9873 -0.0255 0.0134 -0.9888 0.0006 0.0009 0.9997 -1.30862e-10 0.0334976 
> 

-v使得grep返回所有行除了包含字符串TRIAL線。考慮到多年來一直關注命令工具grep的高質量工程師的數量,它很可能是最快的,以及正確,方便,有據可查的在線,易於學習和搜索爲特定任務提供解決方案。如果您需要更復雜的字符串過濾器(例如字符串在行的開頭或結尾等),那麼grep語法非常強大。學習其語法是其他語言和環境的技巧。

有關在fread中使用命令行工具的更多示例,可以查看文章Convenience features of fread。請注意,「在Windows上,我們推薦使用Cygwin(運行一個.exe來安裝),其中包括命令行工具,例如grep」。

+0

您的解決方案非常高雅,非常感謝我的問題。但是當我試圖測試fread(「grep -v TRIAL sum_data.txt」)時,它說'grep'不被識別爲內部或外部命令,可操作的程序或批處理文件。 另外:警告信息: 1:運行命令'C:\ Windows \ system32 \ cmd.exe/c(grep -v TRIAL sum_data.txt) – Alexander

+0

我正在使用'data.table' 1.9.6版本。 – Alexander

+1

@亞歷山大在Windows上,安裝[Cygwin](https://www.cygwin.com/)應該可以做到。 –

1

爲了讀取文件並根據字符串條件刪除行,可以使用readLines函數,並過濾結果。

我使用stringr包進行字符串操作。

library(stringr) 
# Read your file by lines 
DT <- readLines("sum_data") 
length(DT) 
#> [1] 124501 
# detect which lines contains trial 
trial_lines <- str_detect(DT, "TRI") 
head(trial_lines) 
#> [1] TRUE TRUE FALSE FALSE FALSE FALSE 
# Remove those lines 
DT <- DT[!trial_lines] 
length(DT) 
#> [1] 124251 
# Rewrite your file by line 
writeLines(DT, "new_file") 

如果你有性能問題,你可以嘗試從read_linesreadr,而不是基地readLines

+0

我試過你的腳本,它正在工作!但是,如何在刪除'TRIAL'行後選擇一些特定的列。在寫行時可以說'V1','V7'和'V10'? – Alexander