摘要

本篇也是从实际问题出发,至使用R语言解决问题的一篇过程记录。数据源是来自华中科技大学同济医学院一位同学的室友的实验数据。本来问题是十分简单的,就是将每个文件夹下的多个EXCEL表格合并成为一个EXCEL表,但是在过程中出现了意料之外的问题,实验仪器导出的EXCEL文件名过长,导致EXCEL打开文件时会报错,R读取文件时也会报错。最终使用R语言自带的file.rename函数解决了这个问题。

1 处理文件夹名

  • 处理前:处理前的文件夹名长这个样子,虽然读取文件夹路径时未报错,但是为了美观并且剔除无效信息,我们仍然将文件夹名进行标准化处理,使得他们看起来比较顺眼。

R语言文件名 r语言file.rename_R语言文件名

  • 处理后:处理后的文件夹名长这个样子,主要是去除了数字(在本例中,文件夹名中的数字主要是一些编号以及日期之类的字符串),数字虽然包含着一定的信息,但是去除后并不影响识别,各文件夹名仍是唯一值。
  • 处理过程如下:
## set environment

path 'C:/Users/Proka/Desktop/HM数据'
setwd(path)

library(openxlsx)
library(stringr)

## rename.folders

old.file.names new.file.names 
for(i in old.file.names){
  new.file.name "\\d", "", i)
  new.file.name "[^[:alnum:]///' ]", "", new.file.name)
  new.file.names }

file.rename(old.file.names, new.file.names)

以上代码中只有两点需要说明:

  • gsub("\\d", "", i)这一步是用来清除所有数字
  • gsub("[^[:alnum:]///' ]", "", new.file.name)这一步是用来清楚所有特殊符号

2 处理每个文件夹内文件名

处理前的文件夹名有张这样的:00332_20201221004_xxx_OS_2020-12-21_14-25-05_ONH Angio 6x6 512x512 R4_96.5946_AngioDensitySmallVessel_AngioNerveFiber_ETDRS环_2020-12-23_21-49-08,其中xxx表示人名,像这种长度或者长度更长的文件名,EXCEL读取时会提示超过259字符,报错。所以,文件名的处理是必须的。

处理过程如下:

## set environment 

originpath 'C:/Users/Proka/Desktop/HM鏁版嵁'
library(stringr)

## rename.excels

folder.names 
for(i in 1:length(folder.names)){

  folder.path '/', folder.names[i],
'/', 'Quantization', sep = '')

  setwd(folder.path)

  excel.names   
  new.excel.names   
for(j in excel.names){

    new.excel.name "[^[:alnum:]///' ]", "", j)
    new.excel.name "\\d", "", new.excel.name)
    new.excel.name '.csv', sep = '')
    new.excel.names   }

  file.rename(excel.names, new.excel.names)
}

主要是两层循环的嵌套,其他就没有什么好说的了,同样是去除文件名中的数字和特殊符号。

3 文件合并

文件合并是最后一步,也是双重嵌套,没有什么难度,直接给出代码

## set environment

library(openxlsx)
library(stringr)
path 'C:/User/Proka/Desktop/HM数据'

## folder name

folder.names 
## EXCEL names

for(i in 1:length(folder.names)){

  excel.folder.path '/',
                              folder.names[i], '/',
'Quantiztion', sep = '')

  excel.names   
  print(excel.names)

  outputdata   
for(j in excel.names){

    excel.path '/',
                        j, sep = '')

    binddata FALSE)

    outputdata     
  }

  write.path 'C:/Users/Proka/Desktop/OutputEXCEL'

  write.file.name '/',
                           folder.names[i],
'.xlsx', sep = '')

  write.xlsx(outputdata, file = write.file.name)
}

唯一需要说明的地方是,使用paste()函数的时候,sep = ''那里最好每次都设置一下,不然很可能连接起来的结果会与我们想要的结果产生出入。

4  Conclusion

  • 本代码是可复用的,只要改一下文件夹的地址就行