专有的软件生产丑陋的Excel表…我可以把他们到R?

我们收集蝙蝠电话并进行分析,结果是一场噩梦。 我想简化我们的stream程,但我很难过。 如何从Excel中取几十个文件,如下所示:

Excel输出格式

然后得到导入来添加行,这样每两行间隔两行(即3-6,9-12,15-18等行 – 每个项目的间距相同)被导入直到空空间达到了(每个项目会有不同数量的重复)? 我也想endCol在每个四行分段的空白空间…

我可以很容易地指定给定站点的范围,使用:

  df<-t(readWorksheetFromFile("file directory",sheet=2, header=FALSE,startCol=2,startRow=3,endCol=5,endRow=6)) 

然后变得很丑,但是我做了这个:

  colnames(df)<-c("Species","n","percent","mle") BCID.df<-transform(BCID.df,Species=as.character(as.character(Species)), n=as.numeric(as.character(n)),percent=as.numeric(as.character(percent)), mle=as.numeric(as.character(mle))) 

输出格式是我想要的,但我需要修复endRowendCol ,不知道如何…任何build议将非常感激。

我会解决这个很像评论中提到的@Frank。 我把整个事情看成是一个大文件,然后根据文件path信息将它分成一个列表。 一旦这些被分成一个列表,每个数据集可以在一个lapply循环中清理。

我通过readxl::read_excel ,但如果你愿意的话,你可以通过readxl::read_excel via函数读取整个文件。

 library(readxl) orig = read_excel("test.xlsx", col_names = FALSE) 

假冒数据的前六行是这样的:

  X0 X1 X2 X3 X4 X5 X6 <chr> <chr> <chr> <chr> <chr> <chr> <chr> 1 c:\\file directory\\acoustic data\\Site 10\\20160517 <NA> <NA> <NA> <NA> <NA> <NA> 2 identification summary <NA> <NA> <NA> <NA> <NA> <NA> 3 ID EPFU LANO <NA> MID <NA> <NA> 4 N 70 12 <NA> 4 <NA> <NA> 5 % 16 3 <NA> 13 <NA> <NA> 6 MLE(p) 1E-3 2E-3 <NA> <NA> <NA> <NA> 

这个原始文件应该被拆分成单独的表格,这可以基于包含以“c:”开头的文件path信息的行来完成。 要找出它们的位置,请在整个数据集的第一列使用cumsumgrepl

 groups = cumsum(grepl("c:", orig$X0)) 

使用这个向量来分割文件,通过split将每个单独的表格保存到列表中。

 orig_list = split(orig, groups) 

现在剩下的工作是清理每个数据集,转换事物并删除任何额外的行和列。 这也是您可以从文件path中提取“网站”和“date”信息以添加到数据集以保持组织性的地方,这是我演示但不是严格必要的。 我把这一切都放到了lapply使用的函数中。 注意我使用了readr::type_convert来确保数值variables被正确地转换。

 clean_data = function(data) { # Get rid of any empty headers (missing values in first column) new = data[!is.na(data[,1]),] # Transpose new = t(new) # Put into data.frame, removing extraneous columns 1 to 2 # and using first row as variable names # Convert variables to appropriate type at same time using readr::type_convert new2 = readr::type_convert(as.data.frame(new[-1, -(1:2)])) names(new2) = new[1, -(1:2)] # Add site and date columns by pulling info from original "c:\\..." cell new2$site = unlist(strsplit(new[1], "\\\\"))[4] new2$date = unlist(strsplit(new[1], "\\\\"))[5] # Remove everything after first missing ID new2[cumsum(is.na(new2$ID)) == 0,] } 

现在循环所有的块,并清理每一个。 由此产生的清理文件将在列表中。 如果需要的话,你可以把它们绑定到一个数据集中。

 lapply(orig_list, clean_data) 

快速和肮脏,但这应该工作,如果每个块是相同的尺寸,如示例所示:

 library(XLConnect) # Read the whole sheet in once df <- readWorksheetFromFile("file directory",sheet=2, header=FALSE) # Figure out how many code chunks you have (each appears to be 7 rows) nChunks <- floor(nrow(df)/7) # create blank list where you can house the different chunks l <- vector("list", length=nChunks) # Iterate over the chunks reading them each in to their own list element for(i in 1:nChunks){ if(i > 1){ l[[i]] <- t(readWorksheetFromFile("file directory", sheet=2, header=FALSE, startCol=2, startRow=3, endCol=5, endRow=6)) } else{ l[[i]] <- t(readWorksheetFromFile("file directory", sheet=2, header=FALSE, startCol=2, startRow=3+(7*i), endCol=5, endRow=6+(7*i))) } } 

然后你可以做同样的转换,但是乐于利用列表中的块。

不同的可能的列标签使这个有点复杂,但是因为你说有相对较less的一组列名称,所以我只是写一个函数,根据初始名称来replace它们:

 renameCols <- function(x){ # First possible permutation if(identical(colnames(x),c("nameOfColumn1","nameOfColumn2","nameOfColumn3")) {colnames(x) <- c("newName1","newName2","newName3")} # Second possible permutation if(identical(colnames(x),c("nameOfColumn1","nameOfColumn2","nameOfColumn3")) {colnames(x) <- c("newName1","newName2","newName3")} # ... etc return(x) } 

然后将列名replace函数应用于每个块(每个块都存储在列表的不同元素中):

 lapply(l, renameCols) 

我知道这是一个旧的post,但我会加我的.02无论如何。 我认为你应该使用一些简单的VBA来把所有东西都组织到Excel中,然后把一个结构良好的文件读入到R中。我认为像使用Excel这样的事情比使用R的一切事情更容易,就像你可以清楚地看到。 你应该总是使用正确的工具来完成这项工作。