繁体   English   中英

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

[英]Reading and binding multiple CSV files that have different columns in R

我想读取多个具有不同列号和名称的 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",2),
                                                                                   rep("character",8), rep("NULL",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)

****编辑:我确实得到了我正在寻找的合并文件,但有一个例外; 绑定新文件时,某些行(某些文件的)被附加到新列,当我运行 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), function(x, d) ifelse(x %in% d[["df2"]], d[d[["df2"]] == x,]$id, x), d = ref)

bind_rows(df1, df2)

这可以在函数中做得更整洁一些。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM