如何阅读与R合并的Excel单元格

我收到了数百个包含合并单元格的Excel工作表。 发件人坚持使用Excel和合并单元格 – 我无能为力。 我如何阅读这些使用R? 例如,input表的问题区域的简化版本可能看起来像这样,合并的单元格(B2,B3,C2,C3)包含单词“X”。 合并单元格的数量和它们在工作表中的位置(以及“X”的值)在工作表之间变化,并且在同一工作表中可能有多个合并单元格集合。 表单实际上并不是表格格式,而是包含其他空单元格。 我已经成功地通过了所有的文件,清理整个混乱,重塑了结果,并获得了一个整洁的数据集(1张,而不是736 Excel的工作簿)。 问题是,迄今为止我的解决scheme忽略了合并单元格中的信息。

ABCD 1 afil 2 b X m 3 cn 4 dgjo 5 ehkp 

我怎样才能读取到R的Excel表格,使结果看起来像这样,与单词“X”

  ABCD 1 afil 2 b XX m 3 c XX n 4 dgjo 5 ehkp 

如果一个VBA / R混合体适合你的目的,这里是一个VBAmacros,它将在工作表中取消合并所有的单元格,同时用相应的值填充未合并区域中的所有单元格:

 Sub UnMerge(ws As Worksheet) Dim R As Range, c As Range Dim v As Variant For Each c In ws.UsedRange If c.MergeCells Then v = c.Value Set R = c.MergeArea R.UnMerge R.Value = v End If Next c End Sub 

一个简单的testing来显示它是如何被调用的:

 Sub test() UnMerge Sheets(1) End Sub 

sub UnMerged可以用作较大程序的一部分,例如遍历文件夹中的所有.xlsx文件以及文件中所有包含数据的表单,将它们全部取出并保存为.csv文件。

在编辑上 。 本地VBA文件处理有点烦人。 如果我需要迭代多个文件,我倾向于使用相关的脚本语言VBScript。 我不确定您的虚拟Windows是否可以处理VBScript。 我会这样认为,因为VBScript是Windows操作系统的标准部分。 如果是这种情况,请查看下列是否正常(为了安全起见备份文件之后)。 将代码另存为包含您要修改的Excel文件的文件夹中.vbs扩展名的简单文本文件。 然后,只需点击它的图标。 它将遍历包含每个这样的文件中的脚本和取消合并工作表1的目录中的所有.xlx.xlsx文件。 我没有进行广泛的testing,也没有包含任何error handling,但是我在一个包含三个Excel文件的文件夹上进行了testing,每个文件都包含多个合并区域,并在我的Windows机器上运行。 我不知道它是否会在你的Mac上运行:

 Option Explicit Dim fso,fol,f,xl, wb, ws,ext,v,r,c Set fso = WScript.CreateObject("Scripting.FileSystemObject") Set xl = CreateObject("Excel.Application") xl.DisplayAlerts = False xl.ScreenUpdating = False set fol = fso.GetFolder(fso.GetParentFolderName(WScript.ScriptFullName)) For Each f In fol.Files ext = LCase(fso.GetExtensionName(f.Name)) If ext = "xls" Or ext = "xlsx" Then Set wb = xl.Workbooks.Open(f.Path) Set ws = wb.Sheets(1) For Each c In ws.UsedRange If c.MergeCells Then v = c.Value Set R = c.MergeArea R.UnMerge R.Value = v End If Next wb.Save wb.Close End If Next 

如果您只需as.is = TRUE空格填充空单元格,请将数据从Excell中导出为制表符分隔的文本文件,然后将它们作为字符( as.is = TRUE )导入到R ,并用Xreplace空白。最后一行在这个例子中,将所有字符列按照Roland的答案转换为因素,这对于分析更为方便。

 tab <- read.table("yourExcelAsText.txt", sep="\t", header=TRUE, as.is=TRUE) tab[tab==""] <- "X" tab <- as.data.frame(unclass(tab)) 

此解决scheme假定电子表格中只有一个合并区域,并且唯一缺less的值(NAs)是归因于合并的单元格。

码:

 library("openxlsx") data = read.xlsx(xlsxFile = "Book1.xlsx", colNames = F) cl = min(ceiling(which(is.na(data))/dim(data)[1])) rw = min(which(is.na(data))%%dim(data)[1]) data[is.na(data)] = data[rw,cl] 

例:

从excel中读取合并单元格的数据:

  X1 X2 X3 X4 X5 1 1 aqa 11 2 2 bws 22 3 3 ced 33 4 4 d <NA> <NA> 44 5 5 <NA> <NA> <NA> 55 6 6 <NA> <NA> <NA> 66 7 7 guj 77 8 8 hik 88 9 9 iol 99 10 10 jpm 110 

正如你看到的,“d”合并在第4到第6行和第2到第4列。唯一的NAs是由于合并的单元格。

从提出的代码中, clrw查找合并值“d”的列和行。

最后一行查找所有的NAs,并用“d”replace它们。

结果:

  X1 X2 X3 X4 X5 1 1 aqa 11 2 2 bws 22 3 3 ced 33 4 4 ddd 44 5 5 ddd 55 6 6 ddd 66 7 7 guj 77 8 8 hik 88 9 9 iol 99 10 10 jpm 110 

注意:如果您的Excel数据具有列名称,则应删除列名colnames = F

你需要通过案例来解决。 下面的代码解决了像你引用的那样的情况。 我又加了一个。 将文件保存为csv或读取为xlxs。 这for但它可以很容易vector化的速度。

 da=read.table("testtemp.csv",sep=";",na.strings=c("", "NA"),stringsAsFactors = F) #str(da) #add more cases da[5,1]<-da[5,2]<-da[4,2]<-NA da > da V1 V2 V3 V4 1 qfil 2 bx <NA> m 3 c <NA> <NA> n 4 d <NA> jo 5 <NA> <NA> kp #function to find cases cencell=function(da){ #i=2;j=2 fc=data.frame(matrix(NA,nrow(da)-1,3)) ij=1 for (i in 1:(ncol(da)-1)) for (j in 1:(nrow(da)-1)){ cst=c(da[j,i+1],da[j+1,i+1],da[j+1,i]) if(all(is.na(cst))){fc[ij,1:2]<-c(j,i) fc[ij,3]<-da[j,i] ij<-1+ij} } fc[1:(ij-1),] } (ctc=cencell(da)) #replace cases daf=da #i=1 for(i in 1:nrow(ctc)){daf[ctc[i,1]+1,ctc[i,2]]<-ctc[i,3] daf[ctc[i,1]:(ctc[i,1]+1),ctc[i,2]+1]<-ctc[i,3] } daf > daf V1 V2 V3 V4 1 qfil 2 bxxm 3 cxxn 4 ddjo 5 ddkp