读取和绑定R中具有不同列的多个CSV文件

问题描述

我想读取多个具有不同列号和名称的CSV文件,并将它们绑定在一起。当所有文件的列数都相同时,我知道如何执行此操作,但是在列号不同的情况下,我很挣扎。

我在文件中识别出一种模式,可以帮助我进行处理。我基本上想跳过前2列,保留第3列,跳过后两列,保留下8列,并跳过随后的任何列。

这是读取所有文件的功能。我想忽略标题,因为列名不同,并且我使用col类删除了不需要的列。我也只指定我要1-18行。我添加了csv文件的路径作为列名,以标识它来自哪个文件。

read_fun = function(path){
  test = read.csv(path,sep=",",header=F,fill = TRUE,colClasses = c(rep("NULL",2),"character",rep("NULL",rep("character",8),5)),skip = 1,nrows = 17)
  test$question = path
  test
}

然后我使用map行绑定所有文件。

FileList = list.files(pattern = "*.csv",full.names=FALSE,recursive = T)

# read_fun(allfiles[1])
combined_dat <- map_dfr(allfiles,read_fun)

**** 编辑:我确实得到了我要查找的组合文件,但有一个例外;绑定新文件时,(某些文件中的)某些行会附加到NEW列中, 当我运行map_dfr时会出现此警告:

New names:
* `` -> ...1
* `` -> ...2
* `` -> ...3
* `` -> ...4
* `` -> ...5
* ...
New names:
* `` -> ...1
* `` -> ...2
* `` -> ...3
* `` -> ...4
* `` -> ...5
* ...
New names:
* `` -> ...9
New names:
* `` -> ...7
* `` -> ...8
* `` -> ...9
New names:
* `` -> ...4
* `` -> ...5
* `` -> ...6
* `` -> ...7
* `` -> ...8
* ...

这将创建大约11个更多的废话变量,使数据变得毫无意义。行绑定无法正常工作。 我怀疑map_dfr不知道如何处理此类数据。

当我读入没有指定最大列数的文件时,会出现此错误(某些文件中有18列,而其他文件中有15列)。从技术上讲,这不是问题,因为如果我通过col类指定18列,则应该将多余的列读为空白,就可以了。

Warning message:
In read.table(file = file,header = header,sep = sep,quote = quote,:
  cols = 18 != length(data) = 16

对不起,我不知道如何重现此问题。如果您有任何建议,我将不胜感激!

解决方法

遇到类似问题时,我将创建索引数据(通常在Excel中创建),其中索引数据的第一列定义要为每个数据列赋予的名称,然后每个后续列在每个列中均具有实际名称文件。然后,我将文件名映射到所需的名称,以使所有内容保持一致。

类似的方法可能对您有用:

library(dplyr)

df1 <- tibble(a1 = 1:2,b1 = letters[1:2],c1 = NA)
df2 <- tibble(a2 = 3:4,b2 = letters[3:4])

ref <- tibble(id = c("a","b"),df1 = c("a1","b1"),df2 = c("a2","b2"))

names(df1) <- sapply(names(df1),function(x,d) ifelse(x %in% d[["df1"]],d[d[["df1"]] == x,]$id,x),d = ref)
names(df2) <- sapply(names(df2),d) ifelse(x %in% d[["df2"]],d[d[["df2"]] == x,d = ref)

bind_rows(df1,df2)

这可以使函数更简洁。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...