2017-09-14 55 views
1

我需要將許多文件讀入R,進行一些清理,然後將它們合併爲一個數據框。這些文件基本上都是這樣開始的:R導入具有不同數量的初始行的文件以跳過

=~=~=~=~=~=~=~=~=~=~=~= PuTTY log 2016.07.11 09:47:35 =~=~=~=~=~=~=~=~=~=~=~= 
up 
Upload #18 
Reader: S1 Site: AA 
--------- upload 18 start --------- 
Type,Date,Time,Duration,Type,Tag ID,Ant,Count,Gap 
E,2016-07-05,11:45:44.17,"upload 17 complete" 
D,2016-07-05,11:46:24.69,00:00:00.87,HA,900_226000745055,A2,8,1102 
D,2016-07-05,11:46:43.23,00:00:01.12,HA,900_226000745055,A2,10,143 

帶列標題的行是"Type,Date,Time,Duration,Type,Tag ID,Ant,Count,Gap"。數據應該有9列。問題是每個文件頭字符串上面的行數是不同的,所以我不能簡單地使用skip = 5。我也只需要以"D,"開頭的行,其他的一切都是消息,而不是數據。

什麼是最好的方式來閱讀我的文件,確保我有9列和跳過所有的垃圾?
我一直在使用readr()包中的read_csv函數,因爲它迄今爲止產生了最少的格式問題。但是,我願意接受任何新的想法,包括以"D,"開頭的行的方式閱讀。我玩弄使用read.tableskip = grep("Type," readLines(i)),但它似乎沒有正確找到頭字符串。這裏是我的基本代碼:

dataFiles <- Sys.glob("*.*") 
datalist <- list() 
for (i in dataFiles) { 
d01 <- read_csv(i, col_names = F, na = "NA", skip = 35) 
# do clean-up stuff 
datalist[[i]] <- d 
} 
+0

是在'type'列一貫的價值'D'? –

+0

你可以用可重現的數據修改你的問題,以便其他人可以測試它嗎?原則上,你是在正確的道路上,因爲這是一個可以通過讀取數據子集(使用'read_csv'中的'n_max'參數)作爲臨時數據並使用grep來存儲爲每個數據文件跳過適當數量的行。 – dshkol

+0

是@ D.sen,'D'總是在'Type'列中。 – notacodr

回答

1

另一個基本的R解決方案如下:您可以通過行讀取文件,獲取以「D」開頭的行索引和標題行。之後,您只需將這些行分割爲「,」並將其放入data.frame中,並將標題行中的名稱分配給它。

lines <- readLines(i) 
dataRows <- grep("^D,", lines) 

names <- unlist(strsplit(lines[grep("Type,", lines)], split = ",")) 

data <- as.data.frame(matrix(unlist(strsplit(lines[dataRows], ",")), nrow = length(dataRows), byrow=T)) 
names(data) <- names 

輸出:

Type  Date  Time Duration Type   Tag ID Ant Count Gap 
1  D 2016-07-05 11:46:24.69 00:00:00.87 HA 900_226000745055 A2  8 1102 
2  D 2016-07-05 11:46:43.23 00:00:01.12 HA 900_226000745055 A2 10 143 
+0

這是最乾淨,最簡單的解決方案,因爲意外的奇怪格式問題。感謝bmosov01和D.sen提供了有用的選擇。 – notacodr

1

如果你的標題行始終與字Type開始,你可以簡單地忽略從您最初讀的skip選項,然後在標題行之前刪除任何行。下面是一些代碼讓你開始(未測試):

dataFiles <- Sys.glob("*.*") 
datalist <- list() 
for (i in dataFiles) { 
d01 <- read_csv(i, col_names = F, na = "NA") 
headerRow <- which(d01[,1] == 'Type') 
d01 <- d01[headerRow+1,] # This keeps all rows after the header row. 
# do clean-up stuff 
datalist[[i]] <- d 
} 

如果你想保持頭,你可以使用:

for (i in dataFiles) { 
d01 <- read_csv(i, col_names = F, na = "NA") 
headerRow <- which(d01[,1] == 'Type') 
d01 <- d01[headerRow+1,] # This keeps all rows after the header row. 
header <- d01[headerRow,] # Get names from header row. 
setNames(d01, header) # Assign names. 
# do clean-up stuff 
datalist[[i]] <- d 
} 
1

您可以在每個文件中使用自定義函數循環和僅篩選type列中以D開頭的那些列,並在最後將它們全部綁定在一起。如果您希望它們作爲單獨的列表,請刪除bind_rows

load_data <-function(path) { 
    require(dplyr) 
    setwd(path) 
    files <- dir() 
    read_files <- function(x) { 
    data_file <- read.csv(paste(path, "/", x, ".csv", sep = ""), stringsAsFactors = FALSE, na.strings=c("","NA")) 
    row.number <- grep("^Type$", data_file[,1]) 
    colnames(data_file) <- data_file[row.number,] 
    data_file <- data_file[-c(1:row.number+1),] 
    data_file <- data_file %>% 
     filter(grepl("^D", Type)) 
    return(data_file) 
    } 
    data <- lapply(files, read_files) 
} 

list_of_file <- bind_rows(load_data("YOUR_FOLDER_PATH")) 
相關問題